方法3:在代碼的開(kāi)頭處手動(dòng)設(shè)置 import theano theano.config.device = 'gpu' theano.config.floatX = 'float32' 如何保存Keras模型?我們不推薦使用pickle或cPickle來(lái)保存Keras模型 你可以使用
使用 例子: from keras.models import load_modelmodel.save('my_model.h5') # creates a HDF5 file 'my_model.h5'del model # deletes the existing model# returns a compiled model# identical to the previous onemodel = load_model('my_model.h5') 如果你只是希望保存模型的結(jié)構(gòu),而不包含其權(quán)重或配置信息,可以使用: # save as JSONjson_string = model.to_json()# save as YAMLyaml_string = model.to_yaml() 這項(xiàng)操作將把模型序列化為json或yaml文件,這些文件對(duì)人而言也是友好的,如果需要的話(huà)你甚至可以手動(dòng)打開(kāi)這些文件并進(jìn)行編輯。 當(dāng)然,你也可以從保存好的json文件或yaml文件中載入模型: # model reconstruction from JSON:from keras.models import model_from_jsonmodel = model_from_json(json_string)# model reconstruction from YAMLmodel = model_from_yaml(yaml_string) 如果需要保存模型的權(quán)重,可通過(guò)下面的代碼利用HDF5進(jìn)行保存。注意,在使用前需要確保你已安裝了HDF5和其Python庫(kù)h5py model.save_weights('my_model_weights.h5') 如果你需要在代碼中初始化一個(gè)完全相同的模型,請(qǐng)使用: model.load_weights('my_model_weights.h5') 如果你需要加載權(quán)重到不同的網(wǎng)絡(luò)結(jié)構(gòu)(有些層一樣)中,例如fine-tune或transfer-learning,你可以通過(guò)層名字來(lái)加載模型: model.load_weights('my_model_weights.h5', by_name=True) 例如: '''假如原模型為: model = Sequential() model.add(Dense(2, input_dim=3, name='dense_1')) model.add(Dense(3, name='dense_2')) ... model.save_weights(fname)'''# new modelmodel = Sequential()model.add(Dense(2, input_dim=3, name='dense_1')) # will be loadedmodel.add(Dense(10, name='new_dense')) # will not be loaded# load weights from first model; will only affect the first layer, dense_1.model.load_weights(fname, by_name=True) 為什么訓(xùn)練誤差比測(cè)試誤差高很多?一個(gè)Keras的模型有兩個(gè)模式:訓(xùn)練模式和測(cè)試模式。一些正則機(jī)制,如Dropout,L1/L2正則項(xiàng)在測(cè)試模式下將不被啟用。 另外,訓(xùn)練誤差是訓(xùn)練數(shù)據(jù)每個(gè)batch的誤差的平均。在訓(xùn)練過(guò)程中,每個(gè)epoch起始時(shí)的batch的誤差要大一些,而后面的batch的誤差要小一些。另一方面,每個(gè)epoch結(jié)束時(shí)計(jì)算的測(cè)試誤差是由模型在epoch結(jié)束時(shí)的狀態(tài)決定的,這時(shí)候的網(wǎng)絡(luò)將產(chǎn)生較小的誤差。 【Tips】可以通過(guò)定義回調(diào)函數(shù)將每個(gè)epoch的訓(xùn)練誤差和測(cè)試誤差并作圖,如果訓(xùn)練誤差曲線(xiàn)和測(cè)試誤差曲線(xiàn)之間有很大的空隙,說(shuō)明你的模型可能有過(guò)擬合的問(wèn)題。當(dāng)然,這個(gè)問(wèn)題與Keras無(wú)關(guān)?!継BigMoyan】 如何獲取中間層的輸出?一種簡(jiǎn)單的方法是創(chuàng)建一個(gè)新的 from keras.models import Modelmodel = ... # create the original modellayer_name = 'my_layer'intermediate_layer_model = Model(input=model.input, output=model.get_layer(layer_name).output)intermediate_output = intermediate_layer_model.predict(data 此外,我們也可以建立一個(gè)Keras的函數(shù)來(lái)達(dá)到這一目的: from keras import backend as K# with a Sequential modelget_3rd_layer_output = K.function([model.layers[0].input], [model.layers[3].output])layer_output = get_3rd_layer_output([X])[0] 當(dāng)然,我們也可以直接編寫(xiě)Theano和TensorFlow的函數(shù)來(lái)完成這件事 注意,如果你的模型在訓(xùn)練和測(cè)試兩種模式下不完全一致,例如你的模型中含有Dropout層,批規(guī)范化(BatchNormalization)層等組件,你需要在函數(shù)中傳遞一個(gè)learning_phase的標(biāo)記,像這樣: get_3rd_layer_output = K.function([model.layers[0].input, K.learning_phase()], [model.layers[3].output])# output in test mode = 0layer_output = get_3rd_layer_output([X, 0])[0]# output in train mode = 1layer_output = get_3rd_layer_output([X, 1])[0] 如何利用Keras處理超過(guò)機(jī)器內(nèi)存的數(shù)據(jù)集?可以使用 另外,也可以編寫(xiě)一個(gè)每次產(chǎn)生一個(gè)batch樣本的生成器函數(shù),并調(diào)用 這種方式在Keras代碼包的example文件夾下CIFAR10例子里有示范,也可點(diǎn)擊這里在github上瀏覽。 當(dāng)驗(yàn)證集的loss不再下降時(shí),如何中斷訓(xùn)練?可以定義 from keras.callbacks import EarlyStoppingearly_stopping = EarlyStopping(monitor='val_loss', patience=2)model.fit(X, y, validation_split=0.2, callbacks=[early_stopping]) 請(qǐng)參考回調(diào)函數(shù) 驗(yàn)證集是如何從訓(xùn)練集中分割出來(lái)的?如果在 訓(xùn)練數(shù)據(jù)在訓(xùn)練時(shí)會(huì)被隨機(jī)洗亂嗎?是的,如果 驗(yàn)證集的數(shù)據(jù)不會(huì)被洗亂 如何在每個(gè)epoch后記錄訓(xùn)練/測(cè)試的loss和正確率?
hist = model.fit(X, y, validation_split=0.2)print(hist.history) 如何使用狀態(tài)RNN(statful RNN)?一個(gè)RNN是狀態(tài)RNN,意味著訓(xùn)練時(shí)每個(gè)batch的狀態(tài)都會(huì)被重用于初始化下一個(gè)batch的初始狀態(tài)。 當(dāng)使用狀態(tài)RNN時(shí),有如下假設(shè)
要使用狀態(tài)RNN,我們需要
要重置網(wǎng)絡(luò)的狀態(tài),使用:
例子: X # this is our input data, of shape (32, 21, 16)# we will feed it to our model in sequences of length 10model = Sequential()model.add(LSTM(32, batch_input_shape=(32, 10, 16), stateful=True))model.add(Dense(16, activation='softmax'))model.compile(optimizer='rmsprop', loss='categorical_crossentropy')# we train the network to predict the 11th timestep given the first 10:model.train_on_batch(X[:, :10, :], np.reshape(X[:, 10, :], (32, 16)))# the state of the network has changed. We can feed the follow-up sequences:model.train_on_batch(X[:, 10:20, :], np.reshape(X[:, 20, :], (32, 16)))# let's reset the states of the LSTM layer:model.reset_states()# another way to do it in this case:model.layers[0].reset_states() 注意, 如何使用Keras進(jìn)行分布式/多GPU運(yùn)算?Keras在使用TensorFlow作為后端的時(shí)候可以進(jìn)行分布式/多GPU的運(yùn)算,Keras對(duì)多GPU和分布式的支持是通過(guò)TF完成的。 with tf.device('/gpu:0'): x = tf.placeholder(tf.float32, shape=(None, 20, 64)) y = LSTM(32)(x) # all ops in the LSTM layer will live on GPU:0with tf.device('/gpu:1'): x = tf.placeholder(tf.float32, shape=(None, 20, 64)) y = LSTM(32)(x) # all ops in the LSTM layer will live on GPU:1 注意,上例中由LSTM創(chuàng)建的變量不在GPU上:所有的TensorFlow變量總是在CPU上生存,而與它們?cè)谀膭?chuàng)建無(wú)關(guān)。各個(gè)設(shè)備上的變量轉(zhuǎn)換TensorFlow會(huì)自動(dòng)完成。 如果你想在不同的GPU上訓(xùn)練同一個(gè)模型的不同副本,但在不同的副本中共享權(quán)重,你應(yīng)該首先在一個(gè)設(shè)備上實(shí)例化你的模型,然后在不同的設(shè)備上多次調(diào)用該對(duì)象,例如: with tf.device('/cpu:0'): x = tf.placeholder(tf.float32, shape=(None, 784)) # shared model living on CPU:0 # it won't actually be run during training; it acts as an op template # and as a repository for shared variables model = Sequential() model.add(Dense(32, activation='relu', input_dim=784)) model.add(Dense(10, activation='softmax'))# replica 0with tf.device('/gpu:0'): output_0 = model(x) # all ops in the replica will live on GPU:0# replica 1with tf.device('/gpu:1'): output_1 = model(x) # all ops in the replica will live on GPU:1# merge outputs on CPUwith tf.device('/cpu:0'): preds = 0.5 * (output_0 + output_1)# we only run the `preds` tensor, so that only the two# replicas on GPU get run (plus the merge op on CPU)output_value = sess.run([preds], feed_dict={x: data}) 要想完成分布式的訓(xùn)練,你需要將Keras注冊(cè)在連接一個(gè)集群的TensorFlow會(huì)話(huà)上: server = tf.train.Server.create_local_server()sess = tf.Session(server.target)from keras import backend as KK.set_session(sess) 關(guān)于分布式訓(xùn)練的更多信息,請(qǐng)參考這里 如何“凍結(jié)”網(wǎng)絡(luò)的層?“凍結(jié)”一個(gè)層指的是該層將不參加網(wǎng)絡(luò)訓(xùn)練,即該層的權(quán)重永不會(huì)更新。在進(jìn)行fine-tune時(shí)我們經(jīng)常會(huì)需要這項(xiàng)操作。在使用固定的embedding層處理文本輸入時(shí),也需要這個(gè)技術(shù)。 可以通過(guò)向?qū)拥臉?gòu)造函數(shù)傳遞 frozen_layer = Dense(32,trainable=False) 此外,也可以通過(guò)將層對(duì)象的 x = Input(shape=(32,))layer = Dense(32)layer.trainable = Falsey = layer(x)frozen_model = Model(x, y)# in the model below, the weights of `layer` will not be updated during trainingfrozen_model.compile(optimizer='rmsprop', loss='mse')layer.trainable = Truetrainable_model = Model(x, y)# with this model the weights of the layer will be updated during training# (which will also affect the above model since it uses the same layer instance)trainable_model.compile(optimizer='rmsprop', loss='mse')frozen_model.fit(data, labels) # this does NOT update the weights of `layer`trainable_model.fit(data, labels) # this updates the weights of `layer` 如何從Sequential模型中去除一個(gè)層?可以通過(guò)調(diào)用 model = Sequential()model.add(Dense(32, activation='relu', input_dim=784))model.add(Dense(32, activation='relu'))print(len(model.layers)) # '2'model.pop()print(len(model.layers)) # '1' 【Tips】模型的.layers屬性保存了模型中的層對(duì)象,數(shù)據(jù)類(lèi)型是list,在model沒(méi)有 如何在Keras中使用預(yù)訓(xùn)練的模型?我們提供了下面這些圖像分類(lèi)的模型代碼及預(yù)訓(xùn)練權(quán)重:
可通過(guò) from keras.applications.vgg16 impoprt VGG16from keras.applications.vgg19 impoprt VGG19from keras.applications.resnet50 impoprt ResNet50from keras.applications.inception_v3 impoprt InceptionV3model = VGG16(weights='imagenet', include_top=True) 這些代碼的使用示例請(qǐng)參考 下面的圖像分類(lèi)模型提供了模型搭建的代碼和相應(yīng)的預(yù)訓(xùn)練權(quán)重 使用這些預(yù)訓(xùn)練模型進(jìn)行特征抽取或fine-tune的例子可以參考此博客 VGG模型也是很多Keras例子的基礎(chǔ)模型,如: |
|