Keras(一)Sequential與Model模型、Keras基本結構功能


原文鏈接:http://www.one2know.cn/keras1/
原文鏈接:http://www.one2know.cn/keras2/

keras介紹與基本的模型保存

  • 思維導圖
    1.keras網絡結構

    2.keras網絡配置

    3.keras預處理功能
  • 模型的節點信息提取
    config = model.get_config() 把model中的信息,solver.prototext和train.prototext信息提取出來
    model = Model.from_config(config) 用信息建立新的模型對象
    model = Sequential.from_config(config) 用信息建立新的Sequential模型對象
  • 模型概況查詢
    1.模型概況打印
    model.summary()
    2.返回代表模型的JSON字符串,僅包含網絡結構,不包含權值
    from keras.models import model_from_json
    json_string = model.to_json()
    model = model_from_json(json_string)
    3.model.to_yaml:與model.to_json類似,同樣可以從產生的YAML字符串中重構模型
    from keras.models import model_from_yaml
    yaml_string = model.to_yaml()
    model = model_from_yaml(yaml_string)
    4.權重獲取
    model.get_layer() 依據層名或下標獲得層對象
    model.get_weights() 返回模型權重張量的列表,類型為numpy.array
    model.set_weights() 從numpy.array里將權重載入給模型,要求數組具有與model.get_weights()相同的形狀
    model.layers 查看layer信息
  • 模型保存與加載
    model.save_weights(filepath=filepath) 保存權重,文件類型HDF5,后綴.h5
    model.load_weights(filepath, by_name=False) 加載權重到當前模型,設置by_name=True,則只有名字匹配的層才會載入權重
  • 在keras中設置GPU使用的大小,使用keras時候會出現總是占滿GPU顯存的情況,可以通過重設backend的GPU占用情況來進行調節
    import tensorflow as tf
    from keras.backend.tensorflow_backend import set_session
    config = tf.ConfigProto()
    config.gpu_options.per_process_gpu_memory_fraction = 0.3
    set_session(tf.Session(config=config))
  • 更科學地模型訓練與模型保存
    filepath = 'model-ep{epoch:03d}-loss{loss:.3f}-val_loss{val_loss:.3f}.h5'
    from keras.callbacks import ModelCheckpoint
    checkpoint = ModelCheckpoint(filepath, monitor='val_loss', verbose=1, save_best_only=True, mode='min')
    model.fit(x, y, epochs=20, verbose=2, callbacks=[checkpoint], validation_data=(x, y))
    如果val_loss 提高了就會保存,沒有提高就不會保存
  • 在keras中使用tensorboard
    tensorboard能將keras的訓練過程動態的、直觀的顯示出來
    原理:keras的在訓練(fit)的過程中,顯式地生成log日志;使用tf的tensorboard來解析這個log日志,並且通過網站的形式顯示出來
    RUN = RUN + 1 if 'RUN' in locals() else 1 # locals() 函數會以字典類型返回當前位置的全部局部變量。
LOG_DIR = model_save_path + '/training_logs/run{}'.format(RUN)
LOG_FILE_PATH = LOG_DIR + '/checkpoint-{epoch:02d}-{val_loss:.4f}.hdf5'   # 模型Log文件以及.h5模型文件存放地址
tensorboard = TensorBoard(log_dir=LOG_DIR, write_images=True)
checkpoint = ModelCheckpoint(filepath=LOG_FILE_PATH, monitor='val_loss', verbose=1, save_best_only=True)
early_stopping = EarlyStopping(monitor='val_loss', patience=5, verbose=1)
history = model.fit_generator(generator=gen.generate(True),steps_per_epoch=int(gen.train_batches / 4),validation_data=gen.generate(False), validation_steps=int(gen.val_batches / 4),epochs=EPOCHS, verbose=1,callbacks=[tensorboard, checkpoint, early_stopping])

EarlyStopping patience:當early
(1)stop被激活(如發現loss相比上一個epoch訓練沒有下降),則經過patience個epoch后停止訓練。
(2)mode:‘auto’,‘min’,‘max’之一,在min模式下,如果檢測值停止下降則中止訓練。在max模式下,當檢測值不再上升則停止訓練。
模型檢查點ModelCheckpoint
(1)save_best_only:當設置為True時,將只保存在驗證集上性能最好的模型
(2)mode:‘auto’,‘min’,‘max’之一,在save_best_only=True時決定性能最佳模型的評判准則,例如,當監測值為val_acc時,模式應為max,當檢測值為val_loss時,模式應為min。在auto模式下,評價准則由被監測值的名字自動推斷。
(3)save_weights_only:若設置為True,則只保存模型權重,否則將保存整個模型(包括模型結構,配置信息等)
(4)period:CheckPoint之間的間隔的epoch數
可視化tensorboard write_images: 是否將模型權重以圖片的形式可視化

Sequential模型

  • Sequential模型,即序貫模型,為最簡單的線性、從頭到腳的結構順序,不分叉
  • 基本組件
  1. model.add 添加層
  2. model.compile 模型訓練的BP模式設置
  3. model.fit 模型訓練參數設置和訓練
  4. 模型評估
  5. 模型預測
  • add:添加層,train_val.prototxt文件
    add(self,layer)
    例子:
    model.add(Dense(32,activation='relu',input_dim=100))
    model.add(Dropout(0.25))
    除了加層layer,還可以加其他模型add(self,other_model)
  • compile:訓練模式,solver.prototxt文件
    compile(self, optimizer, loss, metrics=None, sample_weight_mode=None)
    參數:
    optimizer:字符串(預定義優化器名)或優化器對象,參考優化器
    loss:字符串(預定義損失函數名)或目標函數,參考損失函數
    metrics:列表,包含評估模型在訓練和測試時的網絡性能的指標,典型用法是metrics=[‘accuracy’]
    sample_weight_mode:如果你需要按時間步為樣本賦權(2D權矩陣),將該值設為“temporal”。默認為“None”,代表按樣本賦權(1D權)。在下面fit函數的解釋中有相關的參考內容。
    kwargs: 使用TensorFlow作為后端請忽略該參數,若使用Theano作為后端,kwargs的值將會傳遞給 K.function
  • fit:模型訓練,train.sh+soler.prototxt(部分)
    fit(self, x, y, batch_size=32, epochs=10, verbose=1, callbacks=None, validation_split=0.0, validation_data=None, shuffle=True, class_weight=None, sample_weight=None, initial_epoch=0)
    參數:
    x:輸入數據,如果模型只有一個輸入,那么x的類型是numpy.array,如果模型有多個輸入,那么x的類型應當為list,list的元素是對應於各個輸入的numpy.array
    y:標簽,numpy.array
    batch_size:整數,指定進行梯度下降時每個batch包含的樣本數。訓練時一個batch的樣本會被計算一次梯度下降,使目標函數優化一步。
    epochs:整數,訓練的輪數,每個epoch會把訓練集輪一遍。
    verbose:日志顯示,0為不在標准輸出流輸出日志信息,1為輸出進度條記錄,2為每個epoch輸出一行記錄
    callbacks:list,其中的元素是keras.callbacks.Callback的對象。這個list中的回調函數將會在訓練過程中的適當時機被調用,參考回調函數
    validation_split:0~1之間的浮點數,用來指定訓練集的一定比例數據作為驗證集。驗證集將不參與訓練,並在每個epoch結束后測試的模型的指標,如損失函數、精確度等。注意,validation_split的划分在shuffle之前,因此如果你的數據本身是有序的,需要先手工打亂再指定validation_split,否則可能會出現驗證集樣本不均勻。
    validation_data:形式為(X,y)的tuple,是指定的驗證集,此參數將覆蓋validation_spilt
    shuffle:布爾值或字符串,一般為布爾值,表示是否在訓練過程中隨機打亂輸入樣本的順序。若為字符串“batch”,則是用來處理HDF5數據的特殊情況,它將在batch內部將數據打亂。
    class_weight:字典,將不同的類別映射為不同的權值,該參數用來在訓練過程中調整損失函數(只能用於訓練)
    sample_weight:權值的numpy.array,用於在訓練時調整損失函數(僅用於訓練)。可以傳遞一個1D的與樣本等長的向量用於對樣本進行1對1的加權,或者在面對時序數據時,傳遞一個的形式為(samples,sequence_length)的矩陣來為每個時間步上的樣本賦不同的權。這種情況下請確定在編譯模型時添加sample_weight_mode=’temporal’。
    initial_epoch: 從該參數指定的epoch開始訓練,在繼續之前的訓練時有用。
  • evaluate:模型評估
    evaluate(self, x, y, batch_size=32, verbose=1, sample_weight=None)
    本函數按batch計算在某些輸入數據上模型的誤差,其參數有:
    x:輸入數據,與fit一樣,是numpy.array或numpy.array的list
    y:標簽,numpy.array
    batch_size:整數,含義同fit的同名參數
    verbose:含義同fit的同名參數,但只能取0或1
    sample_weight:numpy.array,含義同fit的同名參數
  • predict:模型評估
    predict(self, x, batch_size=32, verbose=0)
    predict_classes(self, x, batch_size=32, verbose=1)
    predict_proba(self, x, batch_size=32, verbose=1)
    本函數按batch獲得輸入數據對應的輸出,其參數有:
    函數的返回值是預測值的numpy.array
    predict_classes:本函數按batch產生輸入數據的類別預測結果
    predict_proba:本函數按batch產生輸入數據屬於各個類別的概率
  • on_batch:batch的結果,檢查
    train_on_batch(self, x, y, class_weight=None, sample_weight=None)
    test_on_batch(self, x, y, sample_weight=None)
    predict_on_batch(self, x)
    參數:
    train_on_batch:本函數在一個batch的數據上進行一次參數更新,函數返回訓練誤差的標量值或標量值的list,與evaluate的情形相同。
    test_on_batch:本函數在一個batch的樣本上對模型進行評估,函數的返回與evaluate的情形相同
    predict_on_batch:本函數在一個batch的樣本上對模型進行測試,函數返回模型在一個batch上的預測結果
  • fit_generator,利用迭代器訓練
    利用Python的生成器,逐個生成數據的batch並進行訓練。
    生成器與模型將並行執行以提高效率。
    例如,該函數允許我們在CPU上進行實時的數據提升,同時在GPU上進行模型訓練
    參考鏈接:http://keras-cn.readthedocs.io/en/latest/models/sequential/
    有了該函數,圖像分類訓練任務變得很簡單。
fit_generator(self, generator, steps_per_epoch, epochs=1, verbose=1, callbacks=None, validation_data=None, validation_steps=None, class_weight=None, max_q_size=10, workers=1, pickle_safe=False, initial_epoch=0)

def generate_arrays_from_file(path):
    while 1:
            f = open(path)
            for line in f:
                # 在每行 創建輸入數據和標簽的array數組
                x, y = process_line(line)
                yield (x, y)
        f.close()

model.fit_generator(generate_arrays_from_file('/my_file.txt'),samples_per_epoch=10000, epochs=10)
 

其他的兩個輔助的內容:
evaluate_generator(self, generator, steps, max_q_size=10, workers=1, pickle_safe=False)
predict_generator(self, generator, steps, max_q_size=10, workers=1, pickle_safe=False, verbose=0)
evaluate_generator:本函數使用一個生成器作為數據源評估模型,生成器應返回與test_on_batch的輸入數據相同類型的數據。該函數的參數與fit_generator同名參數含義相同,steps是生成器要返回數據的輪數。
predcit_generator:本函數使用一個生成器作為數據源預測模型,生成器應返回與test_on_batch的輸入數據相同類型的數據。該函數的參數與fit_generator同名參數含義相同,steps是生成器要返回數據的輪數。

案例一:簡單的二分類

from keras.models import Sequential
from keras.layers import Dense,Activation

# 建立模型
model = Sequential() # 初始化
model.add(Dense(32,activation='relu',input_dim=100))
# Dense代表全連接,有32個全連接層,最后接relu,輸入的是100維
model.add(Dense(1,activation='sigmoid')) # 添加新的全連接層
model.compile(optimizer='rmsprop',loss='binary_crossentropy',metrics=['accuracy'])
# compile,跟prototxt一樣,一些訓練參數,solver.prototxt

# 生成數據
import numpy as np
data = np.random.random((1000, 100))
labels = np.random.randint(2, size=(1000, 1))

# 訓練數據
model.fit(data, labels, batch_size=32, nb_epoch =10,verbose=1)
# 版本1.2里面是nb_epoch ,而keras2.0是epochs

print(model.summary())

輸出:

Using TensorFlow backend.
WARNING:tensorflow:From D:\Python37\Lib\site-packages\tensorflow\python\framework\op_def_library.py:263: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.
Instructions for updating:
Colocations handled automatically by placer.
D:/PyCharm 5.0.3/WorkSpace/3.Keras/1.Sequential與Model模型、Keras基本結構功能/1.py:18: UserWarning: The `nb_epoch` argument in `fit` has been renamed `epochs`.
  model.fit(data, labels, batch_size=32, nb_epoch =10,verbose=1)
WARNING:tensorflow:From D:\Python37\Lib\site-packages\tensorflow\python\ops\math_ops.py:3066: to_int32 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use tf.cast instead.
Epoch 1/10
2019-07-08 12:12:29.800285: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2

  32/1000 [..............................] - ETA: 6s - loss: 0.7047 - acc: 0.5000
1000/1000 [==============================] - 0s 229us/step - loss: 0.7101 - acc: 0.5080
Epoch 2/10

  省略了一堆epoch
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_1 (Dense)              (None, 32)                3232      
_________________________________________________________________
dense_2 (Dense)              (None, 1)                 33        
=================================================================
Total params: 3,265
Trainable params: 3,265
Non-trainable params: 0
_________________________________________________________________
None

案例二:多分類-VGG的卷積神經網絡

import numpy as np
import keras
from keras.models import Sequential
from keras.layers import Dense,Dropout,Flatten
from keras.layers import Conv2D,MaxPooling2D
from keras.optimizers import SGD
from keras.utils import np_utils

# 生成數據
x_train = np.random.random((100,100,100,3))
# 100張圖片 每張100*100*3
y_train = keras.utils.to_categorical(np.random.randint(10,size=(100,1)),num_classes=10)
# 100*10
x_test = np.random.random((20,100,100,3))
y_test = keras.utils.to_categorical(np.random.randint(10,size=(20,1)),num_classes=10)
# 20*100
# keras.utils.to_categorical 將一列數字轉化為keras格式的額一堆類

model = Sequential()
# input: 100x100 images with 3 channels -> (110,100,3) tensore.
# this applies 32 convolution filters of size 3x3 each.
model.add(Conv2D(32,(3,3),activation='relu',input_shape=(100,100,3)))
model.add(Conv2D(32,(3,3),activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.25))

model.add(Conv2D(64,(3,3),activation='relu'))
model.add(Conv2D(64,(3,3),activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.25))

model.add(Flatten())
model.add(Dense(256,activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(10,activation='softmax'))

sgd = SGD(lr=0.01,decay=1e-6,momentum=0.9,nesterov=True)
model.compile(loss='categorical_crossentropy',optimizer=sgd)

model.fit(x_train,y_train,batch_size=32,epochs=10)
score = model.evaluate(x_test,y_test,batch_size=32)

Model式模型

  • 比序貫模型要復雜,但是效果很好,可以同時/分階段輸入變量,分階段輸出想要的模型,函數式模型
  • 函數式模型基本屬性與訓練流程
  1. model.layers,添加層信息
  2. model.compile,模型訓練的BP模式設置
  3. model.fit,模型訓練參數設置和訓練
  4. evaluate,模型評估
  5. predict,模型預測
  • 常用Model屬性
    model.layers:組成模型圖的各個層
    model.inputs:模型的輸入張量列表
    model.outputs:模型的輸出張量列表
  • compile 訓練模式設置——solver.prototxt
    compile(self, optimizer, loss, metrics=None, loss_weights=None, sample_weight_mode=None)
    參數:
    optimizer:優化器,為預定義優化器名或優化器對象,參考優化器
    loss:損失函數,為預定義損失函數名或一個目標函數,參考損失函數
    metrics:列表,包含評估模型在訓練和測試時的性能的指標,典型用法是metrics=[‘accuracy’]如果要在多輸出模型中為不同的輸出指定不同的指標,可像該參數傳遞一個字典,例如metrics={‘ouput_a’: ‘accuracy’}
    sample_weight_mode:如果你需要按時間步為樣本賦權(2D權矩陣),將該值設為“temporal”。默認為“None”,代表按樣本賦權(1D權)
  • fit 模型訓練參數設置和訓練
    fit(self, x=None, y=None, batch_size=32, epochs=1, verbose=1, callbacks=None, validation_split=0.0, validation_data=None, shuffle=True, class_weight=None, sample_weight=None, initial_epoch=0)
    參數:
    x:輸入數據,如果模型只有一個輸入,那么x的類型是numpy.array,如果模型有多個輸入,那么x的類型應當為list,list的元素是對應於各個輸入的numpy.array,如果模型的每個輸入都有名字,則可以傳入一個字典,將輸入名與其輸入數據對應起來。
    y:標簽,numpy.array。如果模型有多個輸出,可以傳入一個numpy.array的list。如果模型的輸出擁有名字,則可以傳入一個字典,將輸出名與其標簽對應起來。
    batch_size:整數,指定進行梯度下降時每個batch包含的樣本數。訓練時一個batch的樣本會被計算一次梯度下降,使目標函數優化一步。
    nb_epoch:整數,訓練的輪數,訓練數據將會被遍歷nb_epoch次。Keras中nb開頭的變量均為”number of”的意思
    verbose:日志顯示,0為不在標准輸出流輸出日志信息,1為輸出進度條記錄,2為每個epoch輸出一行記錄
    callbacks:list,其中的元素是keras.callbacks.Callback的對象。這個list中的回調函數將會在訓練過程中的適當時機被調用,參考回調函數
    validation_split:0~1之間的浮點數,用來指定訓練集的一定比例數據作為驗證集。驗證集將不參與訓練,並在每個epoch結束后測試的模型的指標,如損失函數、精確度等。注意,validation_split的划分在shuffle之后,因此如果你的數據本身是有序的,需要先手工打亂再指定validation_split,否則可能會出現驗證集樣本不均勻。
    validation_data:形式為(X,y)或(X,y,sample_weights)的tuple,是指定的驗證集。此參數將覆蓋validation_spilt。
    shuffle:布爾值,表示是否在訓練過程中每個epoch前隨機打亂輸入樣本的順序。
    class_weight:字典,將不同的類別映射為不同的權值,該參數用來在訓練過程中調整損失函數(只能用於訓練)。該參數在處理非平衡的訓練數據(某些類的訓練樣本數很少)時,可以使得損失函數對樣本數不足的數據更加關注。
    sample_weight:權值的numpy.array,用於在訓練時調整損失函數(僅用於訓練)。可以傳遞一個1D的與樣本等長的向量用於對樣本進行1對1的加權,或者在面對時序數據時,傳遞一個的形式為(samples,sequence_length)的矩陣來為每個時間步上的樣本賦不同的權。這種情況下請確定在編譯模型時添加了sample_weight_mode=’temporal’。
    initial_epoch: 從該參數指定的epoch開始訓練,在繼續之前的訓練時有用。
    輸入數據與規定數據不匹配時會拋出錯誤
    fit函數返回一個History的對象,其History.history屬性記錄了損失函數和其他指標的數值隨epoch變化的情況,如果有驗證集的話,也包含了驗證集的這些指標變化情況
  • evaluate,模型評估
    evaluate(self, x, y, batch_size=32, verbose=1, sample_weight=None)
    參數:
    x:輸入數據,與fit一樣,是numpy.array或numpy.array的list
    y:標簽,numpy.array
    batch_size:整數,含義同fit的同名參數
    verbose:含義同fit的同名參數,但只能取0或1
    sample_weight:numpy.array,含義同fit的同名參數
    本函數返回一個測試誤差的標量值(如果模型沒有其他評價指標),或一個標量的list(如果模型還有其他的評價指標),model.metrics_names將給出list中各個值的含義
  • predict 模型預測
    predict(self, x, batch_size=32, verbose=0)
  • 模型檢查 _on_batch
    train_on_batch(self, x, y, class_weight=None, sample_weight=None)
    test_on_batch(self, x, y, sample_weight=None)
    predict_on_batch(self, x)
    train_on_batch:本函數在一個batch的數據上進行一次參數更新,函數返回訓練誤差的標量值或標量值的list,與evaluate的情形相同。
    test_on_batch:本函數在一個batch的樣本上對模型進行評估,函數的返回與evaluate的情形相同;
    predict_on_batch:本函數在一個batch的樣本上對模型進行測試,函數返回模型在一個batch上的預測結果
  • _generator
    fit_generator(self, generator, steps_per_epoch, epochs=1, verbose=1, callbacks=None, validation_data=None, validation_steps=None, class_weight=None, max_q_size=10, workers=1, pickle_safe=False, initial_epoch=0)
    evaluate_generator(self, generator, steps, max_q_size=10, workers=1, pickle_safe=False)

案例一:簡單的單層-全連接網絡

from keras.layers import Input,Dense
from keras.models import Model
from keras.utils import to_categorical
import numpy as np

data = np.random.random((100,100,3))
data = data.reshape(len(data),-1)
labels = to_categorical(np.random.randint(10,size=(100,1)),num_classes=10)

inputs = Input(shape=(300,)) # 返回一個張量

x = Dense(64,activation='relu')(inputs) # inputs代表輸入,x代表輸出

x = Dense(64,activation='relu')(x) #輸入x,輸出x

predictions = Dense(10,activation='softmax')(x) # 輸入x,輸出分類

# This creates a model that includes the Input layer and three Dense layers
model = Model(inputs=inputs,outputs=predictions)
# 該句是函數式模型的經典,可以同時輸入兩個input,然后輸出output兩個模型
model.compile(optimizer='rmsprop',loss='categorical_crossentropy',metrics=['accuracy'])

# 開始訓練
model.fit(data,labels,epochs=3,batch_size=32)

輸出:

Using TensorFlow backend.
WARNING:tensorflow:From D:\Python37\Lib\site-packages\tensorflow\python\framework\op_def_library.py:263: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.
Instructions for updating:
Colocations handled automatically by placer.
WARNING:tensorflow:From D:\Python37\Lib\site-packages\tensorflow\python\ops\math_ops.py:3066: to_int32 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use tf.cast instead.
2019-07-08 16:47:48.627213: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
Epoch 1/3

 32/100 [========>.....................] - ETA: 0s - loss: 2.4095 - acc: 0.0625
100/100 [==============================] - 0s 2ms/step - loss: 2.3387 - acc: 0.1000
Epoch 2/3

 32/100 [========>.....................] - ETA: 0s - loss: 2.2108 - acc: 0.2188
100/100 [==============================] - 0s 50us/step - loss: 2.2436 - acc: 0.1900
Epoch 3/3

 32/100 [========>.....................] - ETA: 0s - loss: 2.1684 - acc: 0.1250
100/100 [==============================] - 0s 50us/step - loss: 2.1797 - acc: 0.2300

案例二:視頻處理

from keras.layers import Input,Dense
from keras.models import load_model

model = load_model('xxxx.h5')

x = Input(shape=(784,)) # This works, and returns the 10-way softmax we defined above.
y = model(x) # model是訓練好的,現在用來做遷移學習
# model里存着權重,輸入x,輸出結果,用來作fine-tuning

from keras.layers import TimeDistributed

input_sequences = Input(shape=(20,784))

processed_sequences = TimeDistributed(model)(input_sequences)

案例三:雙輸入、雙模型輸出:LSTM 時序預測

通過本案例可以了解到Model的精髓在於他的任意性,給編譯者很多的便利。
輸入:
新聞語料;新聞語料對應的時間
輸出:
新聞語料的預測模型;新聞語料+對應時間的預測模型

### 模型一:只針對新聞語料的LSTM模型

from keras.layers import Input,Embedding,LSTM,Dense
from keras.datasets import reuters
from keras.utils import to_categorical

(headline_data, additional_data), (labels, labels) = reuters.load_data(num_words=10000)
labels = to_categorical(labels,num_classes=46)

# 標題輸入:用於接收100個整數的序列,介於1和10000之間
main_input = Input(shape=(1,),dtype='int32',name='main_input')
# 注意:我們可以通過傳遞一個“name”參數來命名任何層
# 一個100詞的BOW序列

# 這個嵌入層將輸入序列編碼成一個密集的512維向量序列
# Embedding層,把100維度再encode成512的句向量,10000指的是詞典單詞總數
x = Embedding(output_dim=512,input_dim=10000,input_length=1)(main_input)

# LSTM將把向量序列轉換為單個向量,包含關於整個序列的信息。
lstm_out = LSTM(32)(x) # units=32,正整數,輸出空間的維數

#然后,我們插入一個額外的損失,使得即使在主損失很高的情況下,LSTM和Embedding層也可以平滑的訓練

auxiliary_output = Dense(1,activation='sigmoid',name='aux_output')(lstm_out)
#再然后,我們將LSTM與額外的輸入數據串聯起來組成輸入,送入模型中

### 模型二:組合模型 新聞語料+時序

import keras
from keras.models import Model

auxiliary_output = Input(shape=(5,),name='aux_input') # 新加入的一個Input,維度=5
x = keras.layers.concatenate([lstm_out,auxiliary_output]) # 組合起來,對應起來

# 我們在上面堆了一個深度密集連接的網絡 組合模型的形式
x = Dense(64,activation='relu')(x)
x = Dense(64,activation='relu')(x)
x = Dense(64,activation='relu')(x)
# 最后我們添加了主要的邏輯回歸層
main_output = Dense(1,activation='sigmoid',name='main_output')(x)

# 最后,我們定義整個2輸入,2輸出的模型
model = Model(inputs=[main_input,auxiliary_output],outputs=[main_output,auxiliary_output])

# 模型定義完畢,下一步編譯模型
# 我們給額外的損失賦0.2的權重,我們可以通過關鍵字參數loss_weights或loss來為不同的輸出設置不同的損失函數或權值
# 這兩個參數均可為Python的列表或字典,這里我們給loss傳遞單個損失函數,這個損失函數會被應用於所有輸出上

# 訓練方式一:兩個模型 一個loss
model.compile(optimizer='rmsprop', loss='binary_crossentropy',loss_weights=[1., 0.2])
model.fit([headline_data, additional_data], [labels, labels],epochs=50, batch_size=32)

# # 訓練方式二:兩個模型 兩個Loss
# model.compile(optimizer='rmsprop',
#                 loss={'main_output': 'binary_crossentropy', 'aux_output': 'binary_crossentropy'},
#               loss_weights={'main_output': 1., 'aux_output': 0.2})
# # And trained it via:
# model.fit({'main_input': headline_data, 'aux_input': additional_data},
#           {'main_output': labels, 'aux_output': labels},
#           epochs=50, batch_size=32)

案例四:共享層:對應關系、相似性

  • 一個節點,分成兩個分支出去
import keras
from keras.layers import Input,LSTM,Dense
from keras.models import Model

tweet_a = Input(shape=(140,256)) # 140個單詞,每個單詞256維度,詞向量
tweet_b = Input(shape=(140,256))
# 若要對不同的輸入共享同一層,就初始化該層一次,然后多次調用它

# 該層可以將矩陣作為輸入,並返回大小為64的向量
shared_lstm = LSTM(64)

# 當我們多次重用同一層實例時,層的權重也將被重用(有效相同層)
encoded_a = shared_lstm(tweet_a)
encoded_b = shared_lstm(tweet_b)

# 連接兩個結果
merged_vector = keras.layers.concatenate([encoded_a, encoded_b], axis=-1)

# 在頂部添加邏輯回歸
predictions = Dense(1, activation='sigmoid')(merged_vector)

# 我們定義了一個可訓練的模型,將tweet輸入與預測相連接
model = Model(inputs=[tweet_a, tweet_b], outputs=predictions)

model.compile(optimizer='rmsprop',loss='binary_crossentropy',metrics=['accuracy'])
model.fit([data_a, data_b], labels, epochs=10) # 訓練

案例五:抽取層節點內容

# 1.單節點
from keras.layers import Input,LSTM,Dense
from keras.layers import Conv2D
a = Input(shape=(140,256))
lstm = LSTM(32)
encoded_a = lstm(a)
assert lstm.output == encoded_a
# 抽取獲得encoded_a的輸出張量

# 2.多節點
a = Input(shape=(140,256))
b = Input(shape=(140,256))

lstm = LSTM(32)
encoded_a = lstm(a)
encoded_b = lstm(b)

assert lstm.get_output_at(0) == encoded_a
assert lstm.get_output_at(1) == encoded_b

# 3.圖像層節點
# 對於input_shape和output_shape也是一樣,如果一個層只有一個節點,或所有的節點都有相同的輸入或輸出shape,那么input_shape和output_shape都是沒有歧義的,並也只返回一個值。但是,例如你把一個相同的Conv2D應用於一個大小為(3,32,32)的數據,然后又將其應用於一個(3,64,64)的數據,那么此時該層就具有了多個輸入和輸出的shape,你就需要顯式的指定節點的下標,來表明你想取的是哪個了
a = Input(shape=(3, 32, 32))
b = Input(shape=(3, 64, 64))
conv = Conv2D(16, (3, 3), padding='same')
conved_a = conv(a)

# Only one input so far, the following will work:
assert conv.input_shape == (None, 3, 32, 32)

conved_b = conv(b)
# now the `.input_shape` property wouldn't work, but this does:
assert conv.get_input_shape_at(0) == (None, 3, 32, 32)
assert conv.get_input_shape_at(1) == (None, 3, 64, 64)

案例六:視覺問答模型

# 這個模型將自然語言的問題和圖片分別映射為特征向量,
# 將二者合並后訓練一個logistic回歸層,從一系列可能的回答中挑選一個。
from keras.layers import Conv2D,MaxPooling2D,Flatten
from keras.layers import Input,LSTM,Embedding,Dense
from keras.models import Model,Sequential
import keras

# 首先,讓我們使用順序模型定義一個視覺模型。
# 該模型將圖像編碼為矢量。
vision_model = Sequential()
vision_model.add(Conv2D(64, (3, 3),activation='relu', padding='same', input_shape=(3, 224, 224)))
vision_model.add(Conv2D(64, (3, 3), activation='relu'))
vision_model.add(MaxPooling2D((2, 2)))
vision_model.add(Conv2D(128, (3, 3), activation='relu', padding='same'))
vision_model.add(Conv2D(128, (3, 3), activation='relu'))
vision_model.add(MaxPooling2D((2, 2)))
vision_model.add(Conv2D(256, (3, 3), activation='relu', padding='same'))
vision_model.add(Conv2D(256, (3, 3), activation='relu'))
vision_model.add(Conv2D(256, (3, 3), activation='relu'))
vision_model.add(MaxPooling2D((2, 2)))
vision_model.add(Flatten())

# 視覺模型的輸出得到張量:
image_input = Input(shape=(3, 224, 224))
encoded_image = vision_model(image_input)

# 接下來,我們定義一個語言模型,將問題編碼為向量。
# 每個問題的長度最多為100個字,我們將把單詞索引為1到9999之間的整數。
question_input = Input(shape=(100,), dtype='int32')
embedded_question = Embedding(input_dim=10000, output_dim=256, input_length=100)(question_input)
encoded_question = LSTM(256)(embedded_question)

# 將問題向量和圖像向量連接起來:
merged = keras.layers.concatenate([encoded_question, encoded_image])

# 訓練一個超過1000個單詞的邏輯回歸:
output = Dense(1000, activation='softmax')(merged)

# 最終的模型:
vqa_model = Model(inputs=[image_input, question_input], outputs=output)

fine-tuning時如何加載No_top的權重

  • 如果你需要加載權重到不同的網絡結構(有些層一樣)中,例如fine-tune或transfer-learning,你可以通過層名字來加載模型:
    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 model
model = Sequential()
model.add(Dense(2, input_dim=3, name="dense_1"))  # will be loaded
model.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)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM