{
"cells": [
{
"cell_type": "markdown",
"id": "2af2050c",
"metadata": {
"id": "2af2050c"
},
"source": [
"# **Tensorflow 簡介**\n",
"Tensorflow 是一個機器學習的開發平台,提供使用者實現 MLP, CNN, RNN 等等的深度學習演算法,以下會介紹 Tensorflow 達到深度學習演算法所需的基本概念。\n",
"\n",
"## 本章節內容大綱\n",
"* ### [建構支援數值計算的高維度矩陣(Tensor, Multidimensional-array)](#Tensor,Multidimensional-array)\n",
"* ### [自動計算微分值(Automatic differentiation)](#AutomaticDifferentiation)\n",
"* ### [模型建置以及訓練(Model construction, training)](#ModelConstruction,training)\n",
"\n",
"---"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "84eb7d44",
"metadata": {
"id": "84eb7d44"
},
"outputs": [],
"source": [
"# 匯入套件\n",
"import tensorflow as tf\n",
"import numpy as np"
]
},
{
"cell_type": "markdown",
"id": "3fd8260c",
"metadata": {
"id": "3fd8260c"
},
"source": [
"\n",
"## 建構支援數值計算的高維度矩陣(Tensor, Multidimensional-array)\n",
"Tensorflow 張量(Tensor),寫法與 numpy 陣列類似,也能任意從 scalar,list,或 ndarray 的型態轉換成 Tensor"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7a3511ef",
"metadata": {
"id": "7a3511ef"
},
"outputs": [],
"source": [
"a = tf.constant([1, 2, 3, 4, 5], dtype='float32')\n",
"print(a)\n",
"\n",
"b = tf.constant(np.array([1, 2, 3, 4, 5]), dtype='float32')\n",
"print(b)\n",
"\n",
"c = tf.convert_to_tensor([1, 2, 3, 4, 5], dtype='float32')\n",
"print(c)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b2422616",
"metadata": {
"id": "b2422616"
},
"outputs": [],
"source": [
"# tf.Tensor -> ndarray\n",
"a.numpy()"
]
},
{
"cell_type": "markdown",
"id": "1ab353a5",
"metadata": {
"id": "1ab353a5"
},
"source": [
"* ### Tensor 性質"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "68ccce48",
"metadata": {
"id": "68ccce48"
},
"outputs": [],
"source": [
"t = tf.random.normal((1, 2, 4))\n",
"\n",
"print('數據類型:', t.dtype) # 數據類型\n",
"print('形狀:', t.shape) # 形狀\n",
"print('維度數:', t.ndim) # 維度數"
]
},
{
"cell_type": "markdown",
"id": "180ddc7f",
"metadata": {
"id": "180ddc7f"
},
"source": [
"* ### Tensor 操作"
]
},
{
"cell_type": "markdown",
"id": "93879ea6",
"metadata": {
"id": "93879ea6"
},
"source": [
"* #### slice\n",
"從 Tensor 中選取部分內容"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e0503983",
"metadata": {
"id": "e0503983"
},
"outputs": [],
"source": [
"t = tf.constant([[0, 1, 2, 3, 4],\n",
" [5, 6, 7, 8, 9],\n",
" [10, 11, 12, 13, 14],\n",
" [15, 16, 17, 18, 19]])\n",
"\n",
"print(t[1:3, 2:])\n",
"print(tf.slice(t, begin=[1, 2], size=[2, 3]))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f0d43df4",
"metadata": {
"id": "f0d43df4"
},
"outputs": [],
"source": [
"t = tf.constant([[[1, 3, 5, 7],\n",
" [9, 11, 13, 15]],\n",
" [[17, 19, 21, 23],\n",
" [25, 27, 29, 31]]])\n",
"\n",
"print(t[1:2, 1:2, 0:2])\n",
"print(tf.slice(t, begin=[1, 1, 0], size=[1, 1, 2]))"
]
},
{
"cell_type": "markdown",
"id": "7e6aa644",
"metadata": {
"id": "7e6aa644"
},
"source": [
"* #### gather\n",
"從 Tensor 中依據"軸向"(axis)以及"索引"(index)選取部分內容"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b85bd541",
"metadata": {
"id": "b85bd541"
},
"outputs": [],
"source": [
"t = tf.constant([0, 1, 2, 3, 4, 5, 6, 7])\n",
"\n",
"print(tf.gather(t,\n",
" indices=[0, 3, 6]))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "700336b2",
"metadata": {
"id": "700336b2"
},
"outputs": [],
"source": [
"t = tf.constant([[0, 5],\n",
" [1, 6],\n",
" [2, 7],\n",
" [3, 8],\n",
" [4, 9]])\n",
"\n",
"print(tf.gather_nd(t,\n",
" indices=[[2], [3], [0]]))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ff6d62b1",
"metadata": {
"id": "ff6d62b1"
},
"outputs": [],
"source": [
"t = tf.constant([[[0, 1, 2],\n",
" [3, 4, 5],\n",
" [6, 7, 8]],\n",
" [[9, 10, 11],\n",
" [12, 13, 14],\n",
" [15, 16, 17]]])\n",
"\n",
"print(tf.gather_nd(t,\n",
" indices=[[0, 0], [0, 2], [1, 0], [1, 2]]))"
]
},
{
"cell_type": "markdown",
"id": "818faf03",
"metadata": {
"id": "818faf03"
},
"source": [
"* #### reshape\n",
"將 Tensor 改變成指定的形狀"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f89b1dc2",
"metadata": {
"id": "f89b1dc2"
},
"outputs": [],
"source": [
"t = [[1, 2, 3],\n",
" [4, 5, 6]]\n",
"print(tf.reshape(t, shape=[6]))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "67bebf3e",
"metadata": {
"id": "67bebf3e"
},
"outputs": [],
"source": [
"t = [[1, 2, 3],\n",
" [4, 5, 6]]\n",
"\n",
"print(tf.reshape(t, shape=[3, 2]))"
]
},
{
"cell_type": "markdown",
"id": "2fb3b2ec",
"metadata": {
"id": "2fb3b2ec"
},
"source": [
"* #### expand_dims\n",
"增加 Tensor 維度"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "35314323",
"metadata": {
"id": "35314323"
},
"outputs": [],
"source": [
"t = tf.random.normal((2, 2, 3))\n",
"\n",
"print(tf.expand_dims(t, axis=0))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "51e0a497",
"metadata": {
"id": "51e0a497"
},
"outputs": [],
"source": [
"t = tf.random.normal(shape=(2, 2, 3))\n",
"\n",
"print(tf.expand_dims(t, axis=-1))"
]
},
{
"cell_type": "markdown",
"id": "4a46d6f1",
"metadata": {
"id": "4a46d6f1"
},
"source": [
"* #### squeeze\n",
"壓縮 Tensor 維度"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "42a53412",
"metadata": {
"id": "42a53412"
},
"outputs": [],
"source": [
"t = tf.random.normal((2, 2, 1))\n",
"\n",
"print(tf.squeeze(t, axis=-1))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3e0f5741",
"metadata": {
"id": "3e0f5741"
},
"outputs": [],
"source": [
"t = tf.random.normal((2, 1, 3, 1))\n",
"\n",
"print(tf.squeeze(t, axis=[1, 3]))"
]
},
{
"cell_type": "markdown",
"id": "ab557ad2",
"metadata": {
"id": "ab557ad2"
},
"source": [
"* #### transpose\n",
"轉置 Tensor"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "bf8fcdde",
"metadata": {
"id": "bf8fcdde"
},
"outputs": [],
"source": [
"t = [[1, 2, 3],\n",
" [4, 5, 6]]\n",
"\n",
"tf.transpose(t, perm=[1, 0])"
]
},
{
"cell_type": "markdown",
"id": "4c116339",
"metadata": {
"id": "4c116339"
},
"source": [
"* #### math\n",
"數學計算,包括加乘除"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "45ebf80a",
"metadata": {
"id": "45ebf80a"
},
"outputs": [],
"source": [
"a = tf.constant([[1, 2],\n",
" [3, 4]])\n",
"b = tf.constant([[1, 1],\n",
" [1, 1]])"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ee8dd8b7",
"metadata": {
"id": "ee8dd8b7"
},
"outputs": [],
"source": [
"print(a + b, '\\n') # element-wise addition\n",
"print(a - b, '\\n') # element-wise subtraction\n",
"print(a * b, '\\n') # element-wise multiplication\n",
"print(a @ b, '\\n') # matrix multiplication"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a5c9facb",
"metadata": {
"id": "a5c9facb"
},
"outputs": [],
"source": [
"print(tf.add(a, b), \"\\n\") # element-wise addition\n",
"print(tf.subtract(a, b), '\\n') # element-wise subtraction\n",
"print(tf.multiply(a, b), \"\\n\") # element-wise multiplication\n",
"print(tf.matmul(a, b), \"\\n\") # matrix multiplication"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9a7827e9",
"metadata": {
"id": "9a7827e9"
},
"outputs": [],
"source": [
"c = tf.constant([[4.0, 5.0], [10.0, 1.0]])\n",
"\n",
"# Find the largest value\n",
"print(tf.reduce_max(c))\n",
"# Compute the average value\n",
"print(tf.reduce_mean(c))\n",
"# Find the index of the largest value\n",
"print(tf.math.argmax(c))"
]
},
{
"cell_type": "markdown",
"id": "cf1db39a",
"metadata": {
"id": "cf1db39a"
},
"source": [
"-------------"
]
},
{
"cell_type": "markdown",
"id": "79af21df",
"metadata": {
"id": "79af21df"
},
"source": [
"Tensorflow 張量與 Numpy 陣列不同的是,又可分為兩種\n",
"* 無法指派新的值的型態 Tensor\n",
"* 可以指派新的值的型態 Variable"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0962c003",
"metadata": {
"id": "0962c003"
},
"outputs": [],
"source": [
"# numpy 陣列\n",
"a = np.ones((1, 2))\n",
"print(a)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "70f40d76",
"metadata": {
"id": "70f40d76"
},
"outputs": [],
"source": [
"# Numpy 陣列可接受指派新的值\n",
"a[0, 0] = 0\n",
"print(a)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8772b5a4",
"metadata": {
"id": "8772b5a4"
},
"outputs": [],
"source": [
"# Tensorflow 張量\n",
"b = tf.ones((1, 2))\n",
"print(b)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1462b82a",
"metadata": {
"id": "1462b82a"
},
"outputs": [],
"source": [
"# Tensorflow 張量不接受指派新的值(以下程式碼會發生錯誤)\n",
"b[0, 0] = 0\n",
"print(b)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "da509938",
"metadata": {
"id": "da509938"
},
"outputs": [],
"source": [
"# Tensorflow 僅能使用 Variable 指派新的值\n",
"v = tf.Variable(tf.ones((1, 2)))\n",
"print(v)\n",
"\n",
"v.assign(tf.zeros((1, 2)))\n",
"print(v)"
]
},
{
"cell_type": "markdown",
"id": "a0b06662",
"metadata": {
"id": "a0b06662"
},
"source": [
"在類神經網絡中,可以訓練的變數都會以 Variable 的形式存在,才能更新數值。\n",
"\n",
"------------------"
]
},
{
"cell_type": "markdown",
"id": "cd838b5c",
"metadata": {
"id": "cd838b5c"
},
"source": [
"\n",
"## 自動計算微分值(Automatic Differentiation)\n",
"在深度學習演算法當中,很重要的部分就是如何做模型的更新,其中牽涉到對變數做偏微分。"
]
},
{
"cell_type": "markdown",
"id": "8a39cc47",
"metadata": {
"id": "8a39cc47"
},
"source": [
">若此函數 $f(x) = x^2+3x-5$ 對 $x$ 做偏微分,則能得到 $f^\\prime(x) = 2x+3$\n",
">\n",
">將 $x = 1$ 代入函數,得到 $f(x)=-1$,$f^\\prime(x) = 5$\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f9961acd",
"metadata": {
"id": "f9961acd"
},
"outputs": [],
"source": [
"def f(x):\n",
" y = x ** 2 + 3 * x - 5\n",
" return y\n",
"\n",
"\n",
"x = tf.Variable(1.0)\n",
"f(x)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b089c994",
"metadata": {
"id": "b089c994"
},
"outputs": [],
"source": [
"with tf.GradientTape() as tape:\n",
" y = f(x)\n",
"g_x = tape.gradient(y, x) # g(x) = f'(x) = dy/dx\n",
"\n",
"g_x"
]
},
{
"cell_type": "markdown",
"id": "0d631bea",
"metadata": {
"id": "0d631bea"
},
"source": [
"\n",
"## 模型建置以及訓練(Model Construction, Training)"
]
},
{
"cell_type": "markdown",
"id": "31a9c8a6",
"metadata": {
"id": "31a9c8a6"
},
"source": [
"\n"
]
},
{
"cell_type": "markdown",
"id": "24990f5c",
"metadata": {
"id": "24990f5c"
},
"source": [
"* ### 適合新手:\n",
"\n",
"以 tf.keras 的方式建構模型以及訓練模型,能夠更快速的完成整個機器學習過程,將會在 Part2,Part3 接續課程中介紹。\n",
"* ### 適合專家:\n",
"\n",
"可以更客製化的建置模型、訓練過程等等,於 Part4 做介紹。(在本課程中將會列為選修內容)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a4554977",
"metadata": {
"id": "a4554977"
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.12"
},
"colab": {
"provenance": []
},
"accelerator": "GPU",
"gpuClass": "standard"
},
"nbformat": 4,
"nbformat_minor": 5
}