群里的小伙伴們都說TF2.0挺不錯(cuò)的,方便了很多勒叠,今天咱也先簡單學(xué)習(xí)一波。
先推薦一個(gè)教程:https://zhuanlan.zhihu.com/c_1091021863043624960
TensorFlow 2.0 使用 Keras 作為開發(fā)者的核心體驗(yàn)去件。今天體驗(yàn)了一把感耙,確實(shí)挺不錯(cuò)的,那么今天就手把手來教學(xué)如何通過TF2.0 + Keras構(gòu)建一個(gè)簡單神經(jīng)網(wǎng)絡(luò)吁脱。
1桑涎、安裝TF2.0虛擬環(huán)境
首先,我們要在電腦里裝一個(gè)tf2.0的虛擬環(huán)境(我的電腦是mac兼贡,windows和linux類似)攻冷。這里使用anaconda的命令:
conda create --name tf2 python=3.6
注意,后面的python版本最好帶上遍希,否則什么庫都不給你裝等曼。這樣,在anaconda的envs路徑下,就多了一個(gè)tf2的虛擬環(huán)境禁谦,我們可以使用activate命令激活它:
source activate tf2
也可以使用deactivate來退出環(huán)境:
source deactivate tf2
接下來胁黑,安裝tensorflow的環(huán)境,我們首先使用清華源:
sudo pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
然后州泊,安裝tf2.0:
sudo pip install tensorflow==2.0.0-alpha
2丧蘸、創(chuàng)建Jupyter環(huán)境
安裝了tf2.0的環(huán)境還不夠,我們還需要把它作為一個(gè)kernel加入到j(luò)upyter環(huán)境中遥皂,執(zhí)行下面兩步:
conda install notebook ipykernel
sudo python -m ipykernel install --name tf2
接下來力喷,使用jupyter notebook命令啟動(dòng)ipython。環(huán)境切換到tf2:
接下來演训,我們導(dǎo)入tf和keras弟孟,看看版本對(duì)不對(duì):
import tensorflow as tf
from tensorflow.keras import layers
print(tf.__version__)
print(tf.keras.__version__)
輸出為:
2.0.0-alpha0
2.2.4-tf
哈哈,我們的環(huán)境算是安裝成功了样悟!接下來拂募,我們這里介紹兩種建立神經(jīng)網(wǎng)絡(luò)的方式,分別是使用tf.keras.Sequential和使用 Keras 函數(shù)式 API創(chuàng)建神經(jīng)網(wǎng)絡(luò)乌奇。
3没讲、使用tf.keras.Sequential創(chuàng)建神經(jīng)網(wǎng)絡(luò)
導(dǎo)入數(shù)據(jù)
這里,我們下載mnist數(shù)據(jù)集:
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
x_train = x_train.reshape([x_train.shape[0], -1])
x_test = x_test.reshape([x_test.shape[0], -1])
print(x_train.shape, ' ', y_train.shape)
print(x_test.shape, ' ', y_test.shape)
print(x_train.dtype)
結(jié)果為
(60000, 784) (60000,)
(10000, 784) (10000,)
uint8
創(chuàng)建神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)
隨后礁苗,我們使用tf.keras.Sequential創(chuàng)建神經(jīng)網(wǎng)絡(luò)爬凑,有兩種使用方式:
方式1
model = tf.keras.Sequential()
model.add(layers.Dense(64,activation='relu',input_shape=(784,)))
model.add(layers.Dense(32,activation='relu',kernel_initializer=tf.keras.initializers.glorot_normal))
model.add(layers.Dense(32,activation='relu',kernel_regularizer=tf.keras.regularizers.l2(0.01)))
model.add(layers.Dense(10,activation='softmax'))
方式2
model = tf.keras.Sequential([
layers.Dense(64, activation='relu', kernel_initializer='he_normal', input_shape=(784,)),
layers.Dense(64, activation='relu', kernel_initializer='he_normal'),
layers.Dense(64, activation='relu', kernel_initializer='he_normal',kernel_regularizer=tf.keras.regularizers.l2(0.01)),
layers.Dense(10, activation='softmax')
])
compile函數(shù)
complie函數(shù),主要是來編譯我們的模型试伙,代碼如下:
model.compile(optimizer=tf.keras.optimizers.Adam(0.001),
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
可以看到嘁信,我們這里主要提供了三個(gè)函數(shù),第一個(gè)是使用的優(yōu)化器optimizer疏叨;第二個(gè)是模型的損失函數(shù)潘靖,這里使用的是sparse_categorical_crossentropy,當(dāng)然也可以寫成loss=tf.keras.losses.SparseCategoricalCrossentropy()蚤蔓,但是卦溢!但是!后一種寫法秀又,在使用save方法保存和加載模型的時(shí)候单寂,是會(huì)報(bào)錯(cuò)的,所以推薦使用字符串的寫法吐辙;第三個(gè)參數(shù)是模型評(píng)估的方式宣决,這里我們使用正確率來評(píng)估模型,當(dāng)然也可以添加更多昏苏。
可以通過model.summary()來查看構(gòu)建的模型:
使用fit函數(shù)訓(xùn)練模型
接下來尊沸,使用fit函數(shù)訓(xùn)練模型
history = model.fit(x_train, y_train, batch_size=256, epochs=100, validation_split=0.3, verbose=0)
這里威沫,我們加入了驗(yàn)證集,batch_size設(shè)置為256洼专,并用history來保存了結(jié)果棒掠。
繪制accuracy曲線
來看看history里面都有什么把,運(yùn)行history.__dict__壶熏。有一個(gè)關(guān)鍵的key是history句柠,保留了每一步的loss、accuracy棒假、val_loss、val_accuracy精盅。我們直接可以使用history.history['accuracy']來訪問每一步訓(xùn)練集的準(zhǔn)確率帽哑,因此我們可以簡單的將其繪制成圖:
import matplotlib.pyplot as plt
plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])
plt.legend(['training', 'validation'], loc='upper left')
plt.show()
要注意的是,之所以會(huì)有accuracy叹俏,是因?yàn)樵赾ompile函數(shù)中加入了metrics=['accuracy']妻枕,之所以會(huì)有val_loss和val_accuracy,是因?yàn)槲覀冊(cè)趂it函數(shù)中加入了validation_split=0.3粘驰。
使用evaluate進(jìn)行模型的評(píng)測
最后屡谐,使用evaluate進(jìn)行模型的評(píng)測:
results = model.evaluate(x_test,y_test)
結(jié)果如下:
4、使用Keras 函數(shù)式 API創(chuàng)建神經(jīng)網(wǎng)絡(luò)
使用tf.keras.Sequential是層的簡單堆疊蝌数,無法表示任意模型愕掏,如具有非序列數(shù)據(jù)流的模型(例如,殘差連接)顶伞。而使用Keras 函數(shù)式 API則可以饵撑。在使用Keras 函數(shù)式 API時(shí),層實(shí)例可調(diào)用并返回張量唆貌。 而輸入張量和輸出張量用于定義 tf.keras.Model 實(shí)例滑潘。
構(gòu)建模型
input_x = tf.keras.Input(shape=(784,))
hidden1 = layers.Dense(64, activation='relu', kernel_initializer='he_normal')(input_x)
hidden2 = layers.Dense(64, activation='relu', kernel_initializer='he_normal')(hidden1)
hidden3 = layers.Dense(64, activation='relu', kernel_initializer='he_normal',kernel_regularizer=tf.keras.regularizers.l2(0.01))(hidden2)
output = layers.Dense(10, activation='softmax')(hidden3)
model2 = tf.keras.Model(inputs = input_x,outputs = output)
模型訓(xùn)練
后面的過程就跟前面一樣了,不再贅述锨咙,直接上代碼:
model2.compile(optimizer=tf.keras.optimizers.Adam(0.001),
#loss=tf.keras.losses.SparseCategoricalCrossentropy(),
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
history = model2.fit(x_train, y_train, batch_size=256, epochs=100, validation_split=0.3, verbose=0)
import matplotlib.pyplot as plt
plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])
plt.legend(['training', 'validation'], loc='upper left')
plt.show()
5语卤、模型的保存和加載
使用save和tf.keras.models.load_model保存和加載模型:
model.save('model.h5')
model1 = tf.keras.models.load_model('model.h5')
results = model1.evaluate(x_test,y_test)
6、添加BN和Dropout
接下來酪刀,我們構(gòu)建一個(gè)更復(fù)雜的網(wǎng)絡(luò)粹舵,在里面加入BN和Dropout:
model4 = tf.keras.Sequential([
layers.Dense(64, activation='relu', input_shape=(784,)),
layers.BatchNormalization(),
layers.Dropout(0.2),
layers.Dense(64, activation='relu'),
layers.BatchNormalization(),
layers.Dropout(0.2),
layers.Dense(64, activation='relu'),
layers.BatchNormalization(),
layers.Dropout(0.2),
layers.Dense(10, activation='softmax')
])
model4.compile(optimizer=tf.keras.optimizers.Adam(0.001),
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
model4.compile(optimizer=tf.keras.optimizers.Adam(0.001),
#loss=tf.keras.losses.SparseCategoricalCrossentropy(),
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
history = model4.fit(x_train, y_train, batch_size=256, epochs=100, validation_split=0.3, verbose=0)
import matplotlib.pyplot as plt
plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])
plt.legend(['training', 'validation'], loc='upper left')
plt.show()
這個(gè)添加BN和Dropout的方式真的是太簡單了。蓖宦。寫到這里齐婴,我有點(diǎn)拿不準(zhǔn)了,先BN還是先Dropout呢稠茂?再進(jìn)一步柠偶,Relu情妖、BN和Dropout的順序是怎樣的呢?
7诱担、思考-先BN還是先Relu毡证?
在想這個(gè)問題之前,我一直認(rèn)為的順序是Relu->BN->Dropout蔫仙,Dropout的順序是最后一個(gè)應(yīng)該是沒有疑問的料睛,關(guān)鍵是Relu和BN的順序。更擴(kuò)展點(diǎn)摇邦,是BN和非線性激活函數(shù)的關(guān)系恤煞。
關(guān)于這個(gè)問題,論文中給出的是先BN施籍,后面接非線性激活函數(shù)居扒。但實(shí)際中,也有人主張先非線性激活函數(shù)丑慎,再是BN喜喂。關(guān)于這個(gè),大家可以看一下知乎的帖子:https://www.zhihu.com/question/283715823竿裂。
實(shí)際應(yīng)用中玉吁,還是都試試吧,哈哈腻异!
最后进副,說一下交流群的進(jìn)群方式:關(guān)注微信公眾號(hào),“小小挖掘機(jī)”捂掰,后臺(tái)回復(fù)“進(jìn)群”即可敢会。