莫煩Tensorflow教程(1~14)
一、Tensorflow結構
import tensorflow as tf
import numpy as np
#create data
x_data=np.random.rand(100).astype(np.float32)
y_data=x_data*0.1+0.3
#create tensorflow structure
Weights=tf.Variable(tf.random_uniform([1],-1.0,1.0)) #一維,範圍[-1,1]
biases=tf.Variable(tf.zeros([1]))
y=Weights*x_data+biases
loss=tf.reduce_mean(tf.square(y-y_data))
#建立優化器,減小誤差,提高引數準確度,每次迭代都會優化
optimizer=tf.train.GradientDescentOptimizer(0.5) #學習效率<1
train=optimizer.minimize(loss)
#初始化變數
init=tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
#train
for step in range(201):
sess.run(train)
if step%20==0:
print(step,sess.run(Weights),sess.run(biases))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
二、Session
import tensorflow as tf
matrix1 = tf.constant([[3, 3]])
matrix2 = tf.constant([[2], [2]])
# matrix multiply
# np.dot(m1,m2)
product = tf.matmul(matrix1, matrix2)
# # method 1
# sess = tf.Session() # Session是一個object,首字母要大寫
# # 只有sess.run()之後,tensorflow才會執行一次
# result = sess.run(product)
# print(result)
# # close 不影響,會顯得更整潔
# sess.close()
# method 2
# with 可以自己關閉會話
with tf.Session() as sess:
result2 = sess.run(product)
print(result2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
三、Variable
import tensorflow as tf
state=tf.Variable(0,name='counter')
# print(state.name)
# 變數+常量=變數
one=tf.constant(1)
new_value=tf.add(state,one)
#將state用new_value代替
updata=tf.assign(state,new_value)
#變數必須要啟用
init=tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
for _ in range(3):
sess.run(updata)
print(sess.run(state))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
四、placeholder
執行到sess.run()的時候再給輸入
利用feed_dict繫結
import tensorflow as tf
# 給定type,tf大部分只能處理float32資料
input1 = tf.placeholder(tf.float32)
input2 = tf.placeholder(tf.float32)
# Tensorflow 1.0 修改版
# tf.mul---tf.multiply
# tf.sub---tf.subtract
# tf.neg---tf.negative
output = tf.multiply(input1, input2)
with tf.Session() as sess:
# placeholder在sess.run()的時候傳入值
print(sess.run(output, feed_dict={input1: [7.], input2: [2.]}))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
五、激勵函式
解決非線性問題
要求:必須可微分
簡單的神經網路一般可以使用任何激勵函式;
複雜的神經網路不能隨意選擇,會造成梯度爆炸和梯度消失的問題;
如何選擇
簡述激勵函式:
讓某一部分的神經元先啟用,傳到後面的神經元,不同的神經元對不同的特徵敏感。
啟用函式的輸出:
啟用 / 抑制
一般的神經網路:
啟用函式就在layer2中
六、新增層
import tensorflow as tf
import numpy as np
def add_layer(inputs,in_size,out_size,activation_function=None):
#Weights是一個矩陣,[行,列]為[in_size,out_size]
Weights=tf.Variable(tf.random_normal([in_size,out_size]))#正態分佈
#初始值推薦不為0,所以加上0.1,一行,out_size列
biases=tf.Variable(tf.zeros([1,out_size])+0.1)
#Weights*x+b的初始化的值,也就是未啟用的值
Wx_plus_b=tf.matmul(inputs,Weights)+biases
#啟用
if activation_function is None:
#啟用函式為None,也就是線性函式
outputs=Wx_plus_b
else:
outputs=activation_function(Wx_plus_b)
return outputs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
七、構建一個神經網路
import tensorflow as tf
import numpy as np
def add_layer(inputs,in_size,out_size,activation_function=None):
#Weights是一個矩陣,[行,列]為[in_size,out_size]
Weights=tf.Variable(tf.random_normal([in_size,out_size]))#正態分佈
#初始值推薦不為0,所以加上0.1,一行,out_size列
biases=tf.Variable(tf.zeros([1,out_size])+0.1)
#Weights*x+b的初始化的值,也就是未啟用的值
Wx_plus_b=tf.matmul(inputs,Weights)+biases
#啟用
if activation_function is None:
#啟用函式為None,也就是線性函式
outputs=Wx_plus_b
else:
outputs=activation_function(Wx_plus_b)
return outputs
"""定義資料形式"""
# (-1,1)之間,有300個單位,後面的是維度,x_data是有300行(300個例子)
x_data=np.linspace(-1,1,300)[:,np.newaxis]
# 加噪聲,均值為0,方差為0.05,大小和x_data一樣
noise=np.random.normal(0,0.05,x_data.shape)
y_data=np.square(x_data)-0.5+noise
xs=tf.placeholder(tf.float32,[None,1])
ys=tf.placeholder(tf.float32,[None,1])
"""建立網路"""
#定義隱藏層,輸入1個節點,輸出10個節點
l1=add_layer(xs,1,10,activation_function=tf.nn.relu)
#定義輸出層
prediction=add_layer(l1,10,1,activation_function=None)
"""預測"""
#損失函式,算出的是每個例子的平方,要求和(reduction_indices=[1],按行求和),再求均值
loss=tf.reduce_mean(tf.reduce_sum(tf.square(ys-prediction),reduction_indices=[1]))
"""訓練"""
#優化演算法,minimize(loss)以0.1的學習率對loss進行減小
train_step=tf.train.GradientDescentOptimizer(0.1).minimize(loss)
init=tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
for i in range(1000):
sess.run(train_step,feed_dict={xs:x_data,ys:y_data})
if i%50==0:
print(sess.run(loss,feed_dict={xs:x_data,ys:y_data}))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
八、視覺化
import tensorflow as tf
import numpy as np
import matplotlib.pylab as plt
def add_layer(inputs,in_size,out_size,activation_function=None):
#Weights是一個矩陣,[行,列]為[in_size,out_size]
Weights=tf.Variable(tf.random_normal([in_size,out_size]))#正態分佈
#初始值推薦不為0,所以加上0.1,一行,out_size列
biases=tf.Variable(tf.zeros([1,out_size])+0.1)
#Weights*x+b的初始化的值,也就是未啟用的值
Wx_plus_b=tf.matmul(inputs,Weights)+biases
#啟用
if activation_function is None:
#啟用函式為None,也就是線性函式
outputs=Wx_plus_b
else:
outputs=activation_function(Wx_plus_b)
return outputs
"""定義資料形式"""
# (-1,1)之間,有300個單位,後面的是維度,x_data是有300行(300個例子)
x_data=np.linspace(-1,1,300)[:,np.newaxis]
# 加噪聲,均值為0,方差為0.05,大小和x_data一樣
noise=np.random.normal(0,0.05,x_data.shape)
y_data=np.square(x_data)-0.5+noise
xs=tf.placeholder(tf.float32,[None,1])
ys=tf.placeholder(tf.float32,[None,1])
"""建立網路"""
#定義隱藏層,輸入1個節點,輸出10個節點
l1=add_layer(xs,1,10,activation_function=tf.nn.relu)
#定義輸出層
prediction=add_layer(l1,10,1,activation_function=None)
"""預測"""
#損失函式,算出的是每個例子的平方,要求和(reduction_indices=[1],按行求和),再求均值
loss=tf.reduce_mean(tf.reduce_sum(tf.square(ys-prediction),reduction_indices=[1]))
"""訓練"""
#優化演算法,minimize(loss)以0.1的學習率對loss進行減小
train_step=tf.train.GradientDescentOptimizer(0.1).minimize(loss)
init=tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
fig=plt.figure()
#連續性的畫圖
ax=fig.add_subplot(1,1,1)
ax.scatter(x_data,y_data)
# 不暫停
plt.ion()
# plt.show()繪製一次就會暫停
# plt.show() #也可以用plt.show(block=False)來取消暫停,但是python3.5以後提供了ion的功能,更方便
for i in range(1000):
sess.run(train_step,feed_dict={xs:x_data,ys:y_data})
if i%50==0:
# print(sess.run(loss,feed_dict={xs:x_data,ys:y_data}))
#嘗試先抹除,後繪製第二條線
#第一次沒有線,會報錯,try就會忽略錯誤,然後緊接著執行下面的步驟
try:
# 畫出一條後抹除掉,去除第一個線段,但是隻有一個,也就是抹除當前的線段
ax.lines.remove(lines[0])
except Exception:
pass
prediction_value=sess.run(prediction,feed_dict={xs:x_data})
lines=ax.plot(x_data,prediction_value,'r-',lw=5) #lw線寬
# 暫停0.1s
plt.pause(0.1)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
九、加速神經網路訓練
網路越複雜,資料越多,引數越多,訓練時間越長,但是往往為了解決複雜的問題,網路複雜度高不可避免,所以要使用某些方法使得網路執行更快。
1. 隨機梯度下降
2. 在引數更新上優化
3. 學習率
十、優化器
是對學習率的改變
從初始的cost慢慢走到最小cost的過程
十一、視覺化 Tensorboard
1. Tensorboard安裝:
pip install tensorboard
1
2. 程式設計獲得logs資料夾下的視覺化檔案
3. 進入cmd,到儲存檔案的路徑下
cd E:\python\mofan Tensorflow\logs
1
4. 啟動Tensorboard
Tensorboard --logdir=logs
1
天吶,不知道哪天手殘把系統變數的Path給刪除了,整了一晚上安裝Tensorboard都出錯,終於發現了是Path的問題,以後還是乖乖的,啥也不敢刪除了。
如何複製其中的內容?
1)右鍵上面的空白邊,出現下面介面:
2)點選“標記”
3)選中,點選“Enter”,就複製了
http://PC-20160519HGCD:6006
1
最好使用google chrome開啟網址,即可看到graphs。
十二、分類學習
28*28=784個資料點,也就是x輸入的大小
總共0~9,也就是y輸出的大小
代表3:
黑色格子表示為分類結果:
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
mnist=input_data.read_data_sets('MNIST_data',one_hot=True)
def add_layer(inputs,in_size,out_size,activation_function=None):
#Weights是一個矩陣,[行,列]為[in_size,out_size]
Weights=tf.Variable(tf.random_normal([in_size,out_size]))#正態分佈
#初始值推薦不為0,所以加上0.1,一行,out_size列
biases=tf.Variable(tf.zeros([1,out_size])+0.1)
#Weights*x+b的初始化的值,也就是未啟用的值
Wx_plus_b=tf.matmul(inputs,Weights)+biases
#啟用
if activation_function is None:
#啟用函式為None,也就是線性函式
outputs=Wx_plus_b
else:
outputs=activation_function(Wx_plus_b)
return outputs
def compute_accuracy(v_xs,v_ys):
#全域性變數
global prediction
#生成預測值,也就是概率,即每個數字的概率
y_pre=sess.run(prediction,feed_dict={xs:v_xs})
#對比預測的資料是否和真實值相等,對比位置是否相等,相等就對了
correct_prediction=tf.equal(tf.arg_max(y_pre,1),tf.arg_max(v_ys,1))
#計算多少個對,多少個錯
#tf.cast(x,dtype),將x資料轉換為dtype型別
accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
result=sess.run(accuracy,feed_dict={xs:v_xs,ys:v_ys})
return result
# define placeholder for inputs to networks
# 不規定有多少個sample,但是每個sample大小為784(28*28)
xs=tf.placeholder(tf.float32,[None,784])
ys=tf.placeholder(tf.float32,[None,10])
#add output layer
prediction=add_layer(xs,784,10,activation_function=tf.nn.softmax)
#the error between prediction and real data
cross_entropy=tf.reduce_mean(-tf.reduce_sum(ys*tf.log(prediction),reduction_indices=[1]))
train_strp=tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)
init=tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
for i in range(2000):
batch_xs,batch_ys=mnist.train.next_batch(100)
sess.run(train_strp,feed_dict={xs:batch_xs,ys:batch_ys})
if i%50==0:
print(compute_accuracy(mnist.test.images,mnist.test.labels))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
結果:
0.1415
0.6516
0.751
0.7875
0.8115
0.8247
0.837
0.8403
0.8448
0.8532
0.8585
0.8594
0.8618
0.8631
0.8644
0.098
0.098
0.098
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
十三、過擬合
分類中的過擬合:
實際:
對十字形的新資料分類錯誤
解決方法:
1)增加資料量
過擬合的原因是模型複雜度和資料量不匹配,也就是資料量太小
當資料量增大時,紅線被拉直,沒有那麼扭曲
2)正則化
WW表示要學習的引數,過擬閤中WW往往變化比較大,為了不讓WW變化太大,在原始誤差集上做些改變,即如果WW變化太大,則讓cost的變化也變大。
3)專門用於神經網路的訓練方法:Dropout regularization
第一次訓練:隨機去掉神經網路節點和網路連線:
第二次訓練:再次隨機去掉一些引數
意義:每一次預測的結果都不會依賴於某部分特定的神經元,例如Regularization,當過度依賴某些WW,這些WW的數值會很大,L1/L2會懲罰大的引數,而Dropout是從根本上不讓其過度依賴某些神經元。
十四、Dropout解決over-fitting
黑色的線是理想的分割線,綠色的曲線就是過擬合的曲線,所以要避免讓機器學習學到綠色的線
第一條是直線擬合,沒有很好的擬合效果,underfit
第二條效果較好,just right
第三條是過擬合,over-fitting
Tensorflow解決overfitting——dropout
Summary:所有需要在TensorBoard上展示的統計結果。
tf.name_scope():為Graph中的Tensor新增層級,TensorBoard會按照程式碼指定的層級進行展示,初始狀態下只繪製最高層級的效果,點選後可展開層級看到下一層的細節。
tf.summary.scalar():新增標量統計結果。
tf.summary.histogram():新增任意shape的Tensor,統計這個Tensor的取值分佈。
tf.summary.merge_all():新增一個操作,代表執行所有summary操作,這樣可以避免人工執行每一個summary op。
tf.summary.FileWrite:用於將Summary寫入磁碟,需要制定儲存路徑logdir,如果傳遞了Graph物件,則在Graph Visualization會顯示Tensor Shape Information。執行summary op後,將返回結果傳遞給add_summary()方法即可。
未使用dropout:
import tensorflow as tf
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelBinarizer
#load data
digits=load_digits()
#0~9的影象
X=digits.data
#y是binary的,表示數字1,就在第二個位置放上1,其餘都為0
y=digits.target
y=LabelBinarizer().fit_transform(y)
#切分
X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=3)
def add_layer(inputs,in_size,out_size,layer_name,activation_function=None):
#Weights是一個矩陣,[行,列]為[in_size,out_size]
Weights=tf.Variable(tf.random_normal([in_size,out_size]))#正態分佈
#初始值推薦不為0,所以加上0.1,一行,out_size列
biases=tf.Variable(tf.zeros([1,out_size])+0.1)
#Weights*x+b的初始化的值,也就是未啟用的值
Wx_plus_b=tf.matmul(inputs,Weights)+biases
#啟用
if activation_function is None:
#啟用函式為None,也就是線性函式
outputs=Wx_plus_b
else:
outputs=activation_function(Wx_plus_b)
# 下面的表示outputs的值
tf.summary.histogram(layer_name+'/outputs',outputs)
return outputs
#define placeholder for inputs to network
xs=tf.placeholder(tf.float32,[None,64])
ys=tf.placeholder(tf.float32,[None,10])
#add output layer
# l1為隱藏層,為了更加看出overfitting,所以輸出給了100
l1=add_layer(xs,64,100,'l1',activation_function=tf.nn.tanh)
prediction=add_layer(l1,100,10,'l2',activation_function=tf.nn.softmax)
#the error between prediction and real data
cross_entropy=tf.reduce_mean(-tf.reduce_sum(ys*tf.log(prediction),reduction_indices=[1]))
#新增標量統計結果
tf.summary.scalar('loss',cross_entropy)
train_step=tf.train.GradientDescentOptimizer(0.6).minimize(cross_entropy)
init=tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
#新增一個操作,代表執行所有summary操作,這樣可以避免人工執行每一個summary op
merged=tf.summary.merge_all()
#summary writer goes in here
train_writer=tf.summary.FileWriter("logs/train",sess.graph)#train為log的子資料夾
test_writer=tf.summary.FileWriter("logs/test",sess.graph)
for i in range(500):
sess.run(train_step,feed_dict={xs:X_train,ys:y_train})
if i%50==0:
#record loss
train_result=sess.run(merged,feed_dict={xs:X_train,ys:y_train})
test_result = sess.run(merged, feed_dict={xs: X_test, ys: y_test})
train_writer.add_summary(train_result,i)
test_writer.add_summary(test_result,i)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
紅色:testdata
綠色:trainingdata
使用dropout:
當train_result=sess.run(merged,feed_dict{xs:X_train,ys:y_train,keep_prob:1})時,也就是訓練資料未使用dropout時,仍然有過擬合
當train_result=sess.run(merged,feed_dict{xs:X_train,ys:y_train,keep_prob:0.5})時,兩者擬合的很好
import tensorflow as tf
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelBinarizer
#load data
digits=load_digits()
#0~9的影象
X=digits.data
#y是binary的,表示數字1,就在第二個位置放上1,其餘都為0
y=digits.target
y=LabelBinarizer().fit_transform(y)
#切分
X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=3)
def add_layer(inputs,in_size,out_size,layer_name,activation_function=None):
#Weights是一個矩陣,[行,列]為[in_size,out_size]
Weights=tf.Variable(tf.random_normal([in_size,out_size]))#正態分佈
#初始值推薦不為0,所以加上0.1,一行,out_size列
biases=tf.Variable(tf.zeros([1,out_size])+0.1)
#Weights*x+b的初始化的值,也就是未啟用的值
Wx_plus_b=tf.matmul(inputs,Weights)+biases
#dropout 主功能,drop掉50%的結果,輸出更新後的結果
Wx_plus_b=tf.nn.dropout(Wx_plus_b,keep_prob)
#啟用
if activation_function is None:
#啟用函式為None,也就是線性函式
outputs=Wx_plus_b
else:
outputs=activation_function(Wx_plus_b)
# 下面的表示outputs的值
tf.summary.histogram(layer_name+'/outputs',outputs)
return outputs
#define placeholder for inputs to network
"""dropout"""
# 確定保留多少結果不被捨棄掉
keep_prob=tf.placeholder(tf.float32)
xs=tf.placeholder(tf.float32,[None,64])
ys=tf.placeholder(tf.float32,[None,10])
#add output layer
# l1為隱藏層,為了更加看出overfitting,所以輸出給了100
l1=add_layer(xs,64,50,'l1',activation_function=tf.nn.tanh)
prediction=add_layer(l1,50,10,'l2',activation_function=tf.nn.softmax)
#the error between prediction and real data
cross_entropy=tf.reduce_mean(-tf.reduce_sum(ys*tf.log(prediction),reduction_indices=[1]))
#新增標量統計結果
tf.summary.scalar('loss',cross_entropy)
train_step=tf.train.GradientDescentOptimizer(0.6).minimize(cross_entropy)
init=tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
#新增一個操作,代表執行所有summary操作,這樣可以避免人工執行每一個summary op
merged=tf.summary.merge_all()
#summary writer goes in here
train_writer=tf.summary.FileWriter("logs/train",sess.graph)#train為log的子資料夾
test_writer=tf.summary.FileWriter("logs/test",sess.graph)
for i in range(500):
# drop掉60%,保持40%不被drop掉
sess.run(train_step,feed_dict={xs:X_train,ys:y_train,keep_prob:0.4})
if i%50==0:
#record loss(不要drop掉任何東西,所以為1)
train_result=sess.run(merged,feed_dict={xs:X_train,ys:y_train,keep_prob:0.5})
test_result = sess.run(merged, feed_dict={xs: X_test, ys: y_test,keep_prob:1})
train_writer.add_summary(train_result,i)
test_writer.add_summary(test_result,i)
---------------------
作者:呆呆的貓
來源:CSDN
原文:https://blog.csdn.net/jiaoyangwm/article/details/79715826
版權宣告:本文為博主原創文章,轉載請附上博文連結!
相關文章
- 【莫煩】python基礎教程Python
- 【莫煩】Threading 多執行緒教程thread執行緒
- 【莫煩】Python MatplotlibPython
- 【莫煩】Multiprocessing 多程式
- tensorflow教程1
- [譯] TensorFlow 教程 #14 – DeepDream
- [譯] TensorFlow 教程 #14 - DeepDream
- 【Tensorflow_DL_Note14】TensorFlow視覺化學習1-Tensorflow與OpenCv混合程式設計視覺化OpenCV程式設計
- Tensorflow教程(一)
- Tensorflow教程(前言)
- Tensorflow教程(前一)
- 莫隊
- Tensorflow教程(2)Tensorflow的常用函式介紹函式
- [譯] TensorFlow 教程 – 07 Inception 模型模型
- Tensorflow快餐教程(4) - 矩陣矩陣
- Tensorflow快餐教程(9)-卷積卷積
- [譯] TensorFlow 教程 - 07 Inception 模型模型
- Tensorflow GPU版本安裝教程GPU
- Tensorflow Error筆記1Error筆記
- tensorflow的各種坑 tensorflow1.x 與 tensorflow2.x
- [教程]一份簡單易懂的 TensorFlow 教程
- 【原創】Struts1.x系列教程(14):動態FormORM
- Tensorflow1.x 與 Tensorflow2.0 的區別
- 【Tensorflow_DL_Note9】Tensorflow原始碼解讀1原始碼
- [譯] TensorFlow 教程 #06 – CIFAR-10
- TensorFlow2.0教程-文字分類文字分類
- Windows安裝tensorflow教程 GPU版WindowsGPU
- Tensorflow 2.x入門教程
- [譯] TensorFlow 教程 #03 - PrettyTensor
- [譯] TensorFlow 教程 #06 - CIFAR-10
- [譯] TensorFlow 教程 #05 - 整合學習
- Tensorflow(1)IT男識別玫瑰
- 莫隊演算法講解(含樹上莫隊)演算法
- TensorFlow筆記(1)——TensorFlow中的相關基本概念筆記
- 莫反小練
- 分塊 and 莫隊
- 莫隊詳解
- [譯] TensorFlow 教程 #13 – 視覺化分析視覺化