keras構建神經網路

12smile25發表於2020-10-05

1、使用keras構建神經網路基本工作流程:
訓練資料–建立模型–配置模型–訓練模型–訓練好的模型做預測、對模型效果進行評估。
(1)建立模型:
在 Keras 中有兩類主要的模型:Sequential 順序模型 和 使用函式式 API 的 Model 類模型。
這些模型有許多共同的方法和屬性:
model.layers 是包含模型網路層的展平列表。
model.inputs 是模型輸入張量的列表。
model.outputs 是模型輸出張量的列表。
model.summary() 列印出模型概述資訊。 它是 utils.print_summary 的簡捷呼叫。
model.get_config() 返回包含模型配置資訊的字典。
通過以下程式碼,就可以根據這些配置資訊重新例項化模型:

config = model.get_config()
model = Model.from_config(config)
或者,對於 Sequential:
model = Sequential.from_config(config)

具體見keras中文文件:https://keras.io/zh/models/about-keras-models/

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

#1、定義模型 通過序貫模型
model=Sequential()#定義了一個序貫模型
#2、疊加網路層
#序貫模型的第一層網路需要定義網路的輸入形狀或尺寸input_shape 或input_dim  資料本身的維度即可  不用包含輸入資料的批量大小batch
#input_shape要求是一個元組型別的資料,input_dim要求是 一個整數型別的資料  input_shape=(784,)等價於 input_dim=784
model.add(Dense(32,input_shape=(784,)))#通過add可以把需要的網路層按照順序一層層的疊加到模型上
model.add(Activation('relu'))
model.add(Dense(10))#Dense和Activation都是keras的網路層
model.add(Activation('softmax'))
#注:Dense全連線層 /稠密層 要求制定神經元的個數 Dense(10)表示這一層有10個神經元輸出資料的shape也是10,
#如果是第一層輸入層還需要制定輸入資料的shape 否則則不需要指定
#Activation啟用層 是對該層的輸出施加啟用函式 常用的啟用函式包括 sigmoid relu tanh等
#Dropout 隨機失活層 是防止模型過擬合的一種方式 Dropout層會指定一個更新引數(0-1之間的概率值) Dropout將在訓練過程中每次更新引數時按一定概率隨即斷開輸入神經元
#model.add(Dropout(0.5))
#也可以省略add 直接將網路層傳遞給序貫模型  如下
# model=Sequential([
#     Dense(32,units=784),
#     Activation('relu'),
#     Dense(10),
#     Activation('softmax')
# ])

#3、模型的編譯  :對模型的學習過程進行配置
#優化器optizmizer  損失函式loss 評價指標列表metrics
model.compile(
    optizmizer='rmsprop',
    loss='mse',
    metrics=['mse','mae']
)
'''
(1)優化器optizmizer 隨機梯度下降演算法 等優化方法
優化演算法決定了神經網路引數以何種方式在訓練中被更新 這是網路訓練前需要知道的 需要在模型訓練前配置好
常見的優化器 SGD Adam RMSprop AdaGrad AdaDelta 
指定優化器 把優化器的名字直接作為引數傳給 optizmizer 即可
有時 需要對優化演算法的引數做一定的設定 比如Clipnorm Clipvalue對梯度進行裁剪 或者設定學習率lr以及學習率的衰減率 decay 
這時需要先設定優化器 在傳遞給optizmizer
sgd=optimiizers.SGD(lr=0.01,decay=0.0001)
model.compile(loss='mean_squared_error',optimizer=sgd)
(2)損失函式loss
迴歸問題常用損失函式 mse/mean_squared_error 均方誤差  mae/mean_absolute_error 平均絕對誤差 
分類問題 categorical_crossentropy 交叉熵
(3)效能評估metrics
和損失函式差不多 
'''
#4、訓練模型
model.fit(X,Y,nb_epoch=150,batch_size=16)
'''
X,Y用於訓練的輸入資料
nb_epoch訓練的輪數 當所有的訓練資料都被訓練了一次之後 被稱為一個opoch
batch_size每一批次的資料量 訓練資料不是一次性被輸入網路進行訓練的,而是分批進入 每一個批量batch都會對網路進行一次引數更新 
'''
#5、使用訓練好的模型進行預測
y_pred=model.predict(x_pred,batch_size=32)
#6、模型的評估  在訓練資料上進行
model.evaluate(X,Y)

(2)配置訓練模型

compile(optimizer, loss=None, metrics=None, loss_weights=None, 
sample_weight_mode=None, weighted_metrics=None, target_tensors=None)

引數說明:
① optimizer: 字串(優化器名)或者優化器物件。
② loss: 字串(目標函式名)或目標函式。 如果模型具有多個輸出,則可以通過傳遞損失函式的字典或列表,在每個輸出上使用不同的損失。模型將最小化的損失值將是所有單個損失的總和。
③ metrics: 在訓練和測試期間的模型評估標準。通常你會使用 metrics = [‘accuracy’]。 要為多輸出模型的不同輸出指定不同的評估標準,還可以傳遞一個字典,如 metrics = {‘output_a’:‘accuracy’}。
④ loss_weights: 指定標量係數(Python浮點數)的可選列表或字典,用於加權不同模型輸出的損失貢獻。 模型將要最小化的損失值將是所有單個損失的加權和,由 loss_weights 係數加權。 如果是列表,則期望與模型的輸出具有 1:1 對映。 如果是張量,則期望將輸出名稱(字串)對映到標量係數。
⑤ sample_weight_mode: 如果你需要執行按時間步取樣權重(2D 權重),請將其設定為 temporal。 預設為 None,為取樣權重(1D)。如果模型有多個輸出,則可以通過傳遞 mode 的字典或列表,以在每個輸出上使用不同的 sample_weight_mode。
⑥ weighted_metrics: 在訓練和測試期間,由 sample_weight 或 class_weight 評估和加權的度量標準列表。
⑦ target_tensors: 預設情況下,Keras 將為模型的目標建立一個佔位符,在訓練過程中將使用目標資料。相反,如果你想使用自己的目標張量(反過來說,Keras 在訓練期間不會載入這些目標張量的外部 Numpy 資料),您可以通過 target_tensors 引數指定它們。它應該是單個張量(對於單輸出 Sequential 模型)。
(3)訓練模型

fit(x=None, y=None, batch_size=None, epochs=1, verbose=1, callbacks=None, 
validation_split=0.0, validation_data=None, shuffle=True, class_weight=None, 
sample_weight=None, initial_epoch=0, steps_per_epoch=None, validation_steps=None)

引數說明具體見 keras中文文件
(4)評估模型

evaluate(x=None, y=None, batch_size=None, verbose=1, sample_weight=None, steps=None)

引數說明:
① x: 訓練資料的 Numpy 陣列。 如果模型中的輸入層被命名,你也可以傳遞一個字典,將輸入層名稱對映到 Numpy 陣列。 如果從本地框架張量饋送(例如 TensorFlow 資料張量)資料,x 可以是 None(預設)。
② y: 目標(標籤)資料的 Numpy 陣列。 如果模型中的輸出層被命名,你也可以傳遞一個字典,將輸出層名稱對映到 Numpy 陣列。 如果從本地框架張量饋送(例如 TensorFlow 資料張量)資料,y 可以是 None(預設)。
③ batch_size: 整數或 None。每次提度更新的樣本數。如果未指定,預設為 32.
④ verbose: 0, 1。日誌顯示模式。0 = 安靜模式, 1 = 進度條。
⑤ sample_weight: 訓練樣本的可選 Numpy 權重陣列,用於對損失函式進行加權(僅在訓練期間)。 您可以傳遞與輸入樣本長度相同的平坦(1D)Numpy 陣列(權重和樣本之間的 1:1 對映),或者在時序資料的情況下,可以傳遞尺寸為 (samples, sequence_length) 的 2D 陣列,以對每個樣本的每個時間步施加不同的權重。在這種情況下,你應該確保在 compile() 中指定 sample_weight_mode=“temporal”。
⑥steps: 整數或 None。 宣告評估結束之前的總步數(批次樣本)。預設值 None。
(5)預測模型

predict(x, batch_size=None, verbose=0, steps=None)

x: 輸入資料,Numpy 陣列(或者如果模型有多個輸入,則為 Numpy 陣列列表)。
batch_size: 整數。如未指定,預設為 32。
verbose: 日誌顯示模式,0 或 1。
steps: 宣告預測結束之前的總步數(批次樣本)。預設值 None。

2、手寫數字識別

import keras
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense,Activation,Dropout
from keras.optimizers import RMSprop

#1、定義程式用到的引數 通常是與訓練過程有關的引數
#每個訓練批量的大小
batch_size=128
#模型的輸出是多少個類別  迴歸問題一般只有一個輸出
num_classes=10
#訓練的輪數
epochs=20

#2、資料準備
(x_train,y_train),(x_test,y_test)=mnist.load_data()
print("train data shape",x_train.shape)
print("train label shape",y_train.shape)
print("test data shape",x_test.shape)
print("test label shape",y_test.shape)
#3、把訓練集中的幾個資料列印出來  灰度影像
import matplotlib.pyplot as plt
plt.subplot(221)
plt.imshow(x_train[0],cmap=plt.get_cmap('gray'))
plt.subplot(222)
plt.imshow(x_train[1],cmap=plt.get_cmap('gray'))
plt.subplot(223)
plt.imshow(x_train[2],cmap=plt.get_cmap('gray'))
plt.subplot(224)
plt.imshow(x_train[3],cmap=plt.get_cmap('gray'))
plt.show()
#4、資料預處理
x_train=x_train.reshape(60000,784)
x_test=x_test.reshape(10000,784)
x_train=x_train.astype('float32')
x_test=x_test.astype('float32')
x_train/=255
x_test/=255
y_train=keras.utils.to_categorical(y_train,num_classes)
y_test=keras.utils.to_categorical(y_test,num_classes)

#5、定義模型
model=Sequential()
model.add(Dense(512,activation='relu',input_shape=(784,)))
model.add(Dropout(0.2))
model.add(Dense(512,activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(num_classes,activation='softmax'))
#列印模型結構圖
print(model.summary())
#6、編譯模型
model.compile(loss='categorical_crossentropy',optimizer=RMSprop(),metrics=['accuracy'])
#7、訓練模型
h=model.fit(x_train,y_train,batch_size=batch_size,epochs=epochs,verbose=1,validation_data=(x_test,y_test))
print(h.history)
#8、評價模型
score=model.evaluate(x_test,y_test,verbose=0)
print('test loss:',score[0])
print('test accuracy:',score[1])
#9、預測模型
y_pred=model.predict(x_test)
print(y_pred)
神經網路模型結構
Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense (Dense)                (None, 512)               401920    
_________________________________________________________________
dropout (Dropout)            (None, 512)               0         
_________________________________________________________________
dense_1 (Dense)              (None, 512)               262656    
_________________________________________________________________
dropout_1 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_2 (Dense)              (None, 10)                5130      
=================================================================
Total params: 669,706
Trainable params: 669,706
Non-trainable params: 0

3、使用生成器批量訓練大量資料
keras中用於模型訓練的函式有3個:

model.fit(x_train, y_train,
          epochs=20,
          batch_size=128)
'''
fit(x=None, y=None, batch_size=None, epochs=1, verbose=1, callbacks=None, 
validation_split=0.0, validation_data=None, shuffle=True, class_weight=None, 
sample_weight=None, initial_epoch=0, steps_per_epoch=None, validation_steps=None)
'''
history_object = model.fit_generator(train_generator, 
                                     steps_per_epoch=samples_per_epoch,
                                      validation_data=validation_generator,
                                      validation_steps=nb_val_samples, 
                                     epochs=nb_epoch, verbose=1,
                                     callbacks=callbacks_list)
train_on_batch(x, y, sample_weight=None, class_weight=None)
import keras
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense,Activation,Dropout
from keras.optimizers import RMSprop

num_classes=10
#使用fit_generator函式批量訓練大量資料
#定義一個生成器用於批量生成資料
def data_generator_mnist(isTrain=True,batchSize=100):
    nb_classes=10
    (X_train,y_train),(X_test,y_test)=mnist.load_data()
    X_train=X_train.reshape(60000,784)
    X_test=X_test.reshape(10000,784)
    X_train=X_train.astype('float32')
    X_test=X_test.astype('float32')
    X_train/=255
    X_test/=255
    Y_train=keras.utils.to_categorical(y_train,num_classes)
    Y_test=keras.utils.to_categorical(y_test,num_classes)
    if(isTrain):
        dataset=(X_train,Y_train)
    else:
        dataset = (X_test, Y_test)
    dataset_size=dataset[0].shape[0]
    while(True):
        i=0
        yield dataset[0][i:i+batchSize],dataset[1][i:i+batchSize]
        i+=batchSize
        if (i+batchSize>dataset_size):
            i=0

model=Sequential()
model.add(Dense(512,activation='relu',input_shape=(784,)))
model.add(Dropout(0.2))
model.add(Dense(512,activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(num_classes,activation='softmax'))
model.compile(loss='categorical_crossentropy',optimizer=RMSprop(),metrics=['accuracy'])

history=model.fit_generator(data_generator_mnist(True,batchSize=100),steps_per_epoch=60000,epochs=1,validation_data=data_generator_mnist(False,batchSize=100),validation_steps=10000)
scores=model.evaluate_generator(data_generator_mnist(False),steps=10000)
print("baseline error:%.2f%%"%(100-scores[1]*100))

60000/60000 [==============================] - 937s 16ms/step - loss: 1.6444e-04 - accuracy: 1.0000 - val_loss: 2.4502 - val_accuracy: 0.7400
baseline error:26.00%

python中yield的理解:見部落格 https://blog.csdn.net/mieleizhi0522/article/details/82142856
4、在keras中重複使用模型
在定義好模型結構之後,可以儲存模型,將來可以把這個儲存好的模型載入出來,以便重複使用這個模型。
keras通常使用HDF5檔案的格式來儲存模型,檔案包含的格式如下:模型的結構、模型的權值、訓練配置、優化器的狀態。
將模型的一切打包成HDF5檔案:model.save(‘my_model.h5’)
載入模型:
from keras.models import load_model
model=load_model(‘my_model.h5’)

相關文章