kaggle貓狗分類的總結(AlexNet模型, keras框架),完整實驗流程,源代碼和詳細解析

現在將已掌握的知識進行總結,方便以後自己寫網絡增加思路。

首先數據集下載:鏈接:https://pan.baidu.com/s/1U4N0PCNfyIP9iHLidVb9xA 提取碼:vcvl
keras框架中文文檔:https://keras.io/zh/  英文文檔: https://keras.io/

  • 說一下這個數據集的構成:
    train文件夾下有25000張貓狗照片,貓和狗各12500張,命名方式分別爲cat.x.jpg(x爲索引0, 1, 2,… )(注意cat後邊也有一個點!!),dog.x.jpg。
    test1文件夾下有12500張貓狗混合照片。

1、數據集製作:

  • 分類任務爲例,製作好數據集包括圖像和對應的標籤。需要將數據和標籤一一對應上。
    由於使用train中的照片實在是太多(不適合在CPU跑),我就選擇了250張貓和250張狗的照片作爲訓練集,選100張貓和100張狗照片作爲測試集。
    測試集和訓練集我都在train文件夾中選擇。(test1文件夾是混合貓狗,不方便打標籤)
    在train文件夾選0-249的貓和0-249的狗作爲訓練集,選250-349的貓和250-349的狗作爲測試集。
    所以重新制作的數據集如下圖:
    在這裏插入圖片描述
    在這裏插入圖片描述
    所以文件路徑就是:

    data
        train
         cats (250張貓,編號0-249)
         dogs (250張狗, 編號0-249)
        test
          cats (100張貓, 編號250-349)
         dogs (100張狗, 編號250-349)


放置一個train–cats文件夾詳情給大家,方便看。
到現在,數據集已經制作完畢。

2、 數據預處理

  • 將數據重新定義成標準尺寸image.shape = (224, 224, 3),還可以根據圖像生成器(ImageGenerator)增加圖像數量,提高訓練精度。(我沒有用,這個數據集夠多,沒有必要,這個生成器也很簡單,可以自行百度學習)
    代碼段
IMG_CHANNELS=3 #PGB圖像爲三通道 R、G、B
#weight_decay = 0.0005 
IMG_ROWS=224  #圖像的行像素
IMG_COLS=224  #圖像的列像素
BATCH_SIZE=64 #batch大小
NB_EPOCH=10   #循環次數
NB_CLASSES=2  #分類  貓和狗兩種
VERBOSE=1
#VALIDATION_SPLIT=0.2
#OPTIM=RMSprop()
x_test=np.empty((200,IMG_ROWS,IMG_COLS,3),np.float16)  #測試集兩百張(200, 224, 224, 3)
x_train=np.empty((500,IMG_ROWS,IMG_COLS,3),np.float16)  #訓練集五百張(500, 224, 224, 3)
train_data=np.zeros(500)  #訓練集標籤
test_data=np.zeros(200)  #測試集標籤
#讀入訓練樣本
for i in range(500):
    if i<250:
		#載入250張貓
        train_data[i]=1#貓的標籤就是1
		#dog.8
        imagepath = "D:/python_pro/deep_learning_al/data/train/cats/cat." + str(i)+ ".jpg"#貓照片存儲路徑
        image1 = cv2.imread(imagepath)  #讀入文件
        image1 = cv2.cvtColor(image1, cv2.COLOR_BGR2RGB)  #轉爲RGB
        image1 = cv2.resize(image1,(IMG_ROWS,IMG_COLS))  #重新定義形狀爲(224, 224)
        #plt.imshow(image1)
        #plt.show()
        x_train[i,:,:,:]=image1   #訓練集矩陣,四維(500, 224, 224, 3)

    else:
		#載入250張狗
        train_data[i]=0#狗的標籤就是0
        imagepath = "D:/python_pro/deep_learning_al/data/train/dogs/dog." + str(i - 250)+ ".jpg" #狗照片路徑
        image1 = cv2.imread(imagepath)  #讀入文件
        image1 = cv2.cvtColor(image1, cv2.COLOR_BGR2RGB)#轉爲RGB
        image1 = cv2.resize(image1, (IMG_ROWS, IMG_COLS))#重新定義形狀爲(224, 224)
        x_train[i, :, :, :] = image1 #訓練集矩陣,四維(500, 224, 224, 3)
y_train=to_categorical(train_data) #訓練集標籤(500, 2)
x_train=np.array(x_train)  #完整訓練集矩陣
#讀入測試樣本
for i in range(200):
    if i<100:
		#載入100張貓
        test_data[i]=1#貓的標籤就是1
        imagepath =  "D:/python_pro/deep_learning_al/data/test/cats/cat."+str(i+250)+'.jpg'#貓照片存儲路徑
        image1 = cv2.imread(imagepath)#讀入文件
        image1 = cv2.cvtColor(image1, cv2.COLOR_BGR2RGB)#轉爲RGB
        image1 = cv2.resize(image1,(IMG_ROWS,IMG_COLS)) #重新定義形狀爲(224, 224)
        x_test[i,:,:,:]=image1

    else:
		#載入100張狗
        test_data[i]=0#狗的標籤就是0
        imagepath=  "D:/python_pro/deep_learning_al/data/test/dogs/dog."+str(i+250-100)+'.jpg'#狗照片路徑
        image1 = cv2.imread(imagepath)#讀入文件
        image1 = cv2.cvtColor(image1, cv2.COLOR_BGR2RGB)#轉爲RGB
        image1 = cv2.resize(image1, (IMG_ROWS, IMG_COLS))#重新定義形狀爲(224, 224)
        x_test[i, :, :, :] = image1
y_test=to_categorical(test_data) #測試集標籤(200, 2)
#print(sys.getsizeof(x_test),sys.getsizeof(y_test))
x_test=np.array(x_test) #完整測試集矩陣(200, 224, 224, 3)
#歸一化
#x_train.shape = (500, 224, 224, 3)
#x_test.shape = (200, 224, 224, 3)
x_train=x_train/255  #像素是8位的,所以0-255編程0-1除以255即可。
x_test = x_test/255

print(x_train.shape,x_test.shape,y_train.shape,y_test.shape)

到這裏數據預處理完畢(詳細的註釋已經給出。)

3、定義訓練模型

  • 可以完全自己寫,也可以直接在框架中調用add,來增加層(卷積層,drop out 層,全連接層等)。

  • 我使用的是書中的alexnet模型

  • AlexNet模型簡單介紹:
    網絡架構一共有5個卷積層,3個Maxpooling層、2個全連接層(值得注意的是三、四卷積層後沒有Pooling層),其輸入矩陣爲3x224×224大小的三通道彩色圖像。
    下面爲AlexNet網絡模型架構詳情。
    輸入層(Input):輸入爲3×224×224大小圖像矩陣。
    卷積層(Conv1):96個11*11大小的卷積核(每個GPU上48個卷積核)。
    Pooling層(Pool1):Max Pooling窗口大小爲2×2,stride=2。
    卷積層(Conv2):256個5×5大小的卷積核(每個GPU上128個卷積核)。
    Pooling層(Pool2):Max Pooling窗口大小爲2×2,stride=2。
    卷積層(Conv3):384個3×3大小的卷積核(每個GPU上各192個卷積核)。
    卷積層(Conv4)384個3x3大小的卷積核(每個GPU上各192個卷積核)。
    卷積層(Conv5):256個3x3大小的卷積核(每個GPU上各128個卷積核)。
    Pooling層(Pool5):Max Pooling窗口大小爲2×2,stride=2。
    全連接層(FC1):第一個全連接層,將第五層Pooling層的輸出連接成爲一個一維向量作爲該層的輸入,輸出4096個神經節點。
    全連接層(FC2):第二個全連接層,輸入輸出均爲4096個神經節點。
    Sofmax輸出層:輸出爲1000個神經節點,輸出的每個神經節點單獨對應圖像所屬分類的概率。因爲在ImageNet數據集中有1000個分類,因此設定輸出維度爲1000。們用於二分類,所以輸出爲2個神經節點)

代碼段:

def alex_net(w_path = None):
	#輸入圖像爲(3, 224, 224)
	input_shape = (224, 224, 3)
	#輸入層
	inputs = Input(shape = input_shape, name = 'input')

	#第一層:兩個卷積操作和兩個pooling操作

	conv1_1 = Convolution2D(48, (11, 11), strides = (4, 4), activation = 'relu', name = 'conv1_1')(inputs)
	conv1_2 = Convolution2D(48, (11, 11), strides = (4, 4), activation = 'relu', name = 'conv1_2')(inputs)

	pool1_1 = MaxPooling2D((3, 3), strides = (2, 2), name = 'pool1_1')(conv1_1)
	pool1_2 = MaxPooling2D((3, 3), strides = (2, 2), name = 'pool1_2')(conv1_2)

	#layer2:兩個卷積,將前邊的池化得到的數據,進行卷積,再繼續池化

	conv2_1 = Convolution2D(128, (5, 5), activation = 'relu', padding = 'same')(pool1_1)
	conv2_2 = Convolution2D(128, (5, 5), activation = 'relu', padding = 'same')(pool1_2)

	pool2_1 = MaxPooling2D((3, 3), strides = (2, 2), name = 'pool2_1')(conv2_1)
	pool2_2 = MaxPooling2D((3, 3), strides = (2, 2), name = 'pool2_2')(conv2_2)

	#merge合併層:第二層進入第三層,將數據混合合併
	merge1 = concatenate([pool2_2, pool2_1], axis = 1)

	#layer3:兩個卷積操作

	conv3_1 = Convolution2D(192, (3, 3), activation = 'relu', name = 'conv3_1', padding = 'same')(merge1)
	conv3_2 = Convolution2D(193, (3, 3), activation = 'relu', name = 'conv3_2', padding = 'same')(merge1)

	#latyer4:兩個卷積操作
	conv4_1 = Convolution2D(192, (3, 3), activation = 'relu', name = 'conv4_1', padding = 'same')(conv3_1)
	conv4_2 = Convolution2D(192, (3, 3), activation = 'relu', name = 'conv4_2', padding = 'same')(conv3_2)

	#layer5:兩個卷積操作和兩個pooling操作
	conv5_1 = Convolution2D(128, (3, 3), activation = 'relu', name = 'conv5_1', padding = 'same')(conv4_1)
	conv5_2 = Convolution2D(128, (3, 3), activation = 'relu', name = 'conv5_2', padding = 'same')(conv4_2)

	pool5_1 = MaxPooling2D((3, 3), strides = (2, 2), name = 'pool5_1')(conv5_1)
	pool5_2 = MaxPooling2D((3, 3), strides = (2, 2), name = 'pool5_2')(conv5_2)

	#merge合併層:第五層進入全連接之前,要將分開的合併
	merge2 = concatenate([pool5_1, pool5_2], axis = 1)

	#通過flatten將多維輸入一維化
	dense1 = Flatten(name = 'flatten')(merge2)

	#layer6, layer7 第六,七層, 進行兩次4096維的全連接,中間加dropout避免過擬合
	dense2_1 = Dense(4096, activation = 'relu', name = 'dense2_1')(dense1)
	dense2_2 = Dropout(0.5)(dense2_1)

	dense3_1 = Dense(4096, activation = 'relu', name = 'dense3_1')(dense2_2)
	dense3_2 = Dropout(0.5)(dense3_1)

	#輸出層:輸出類別,分類函數使用softmax

	dense3_3 = Dense(nb_classes, name = 'dense3_3')(dense3_2)
	prediction = Activation('softmax', name = 'softmax')(dense3_3)
	

	#最後定義模型輸出
	AlexNet = Model(input = inputs, outputs = prediction)
	if(w_path):
		#加載權重數據
		AlexNet.load_weights(w_path)
		
	return AlexNet

我將模型寫成了一個函數,封裝起來,方便隨時調用。

使用語句

AlexNet = alex_net()
AlexNet.summary()

可以得到模型的詳細信息。

   AlexNet = Model(input = inputs, outputs = prediction)
__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to
==================================================================================================
input (InputLayer)              (None, 224, 224, 3)  0
__________________________________________________________________________________________________
conv1_2 (Conv2D)                (None, 54, 54, 48)   17472       input[0][0]
__________________________________________________________________________________________________
conv1_1 (Conv2D)                (None, 54, 54, 48)   17472       input[0][0]
__________________________________________________________________________________________________
pool1_2 (MaxPooling2D)          (None, 26, 26, 48)   0           conv1_2[0][0]
__________________________________________________________________________________________________
pool1_1 (MaxPooling2D)          (None, 26, 26, 48)   0           conv1_1[0][0]
__________________________________________________________________________________________________
conv2d_2 (Conv2D)               (None, 26, 26, 128)  153728      pool1_2[0][0]
__________________________________________________________________________________________________
conv2d_1 (Conv2D)               (None, 26, 26, 128)  153728      pool1_1[0][0]
__________________________________________________________________________________________________
pool2_2 (MaxPooling2D)          (None, 12, 12, 128)  0           conv2d_2[0][0]
__________________________________________________________________________________________________
pool2_1 (MaxPooling2D)          (None, 12, 12, 128)  0           conv2d_1[0][0]
__________________________________________________________________________________________________
concatenate_1 (Concatenate)     (None, 24, 12, 128)  0           pool2_2[0][0]
                                                                 pool2_1[0][0]
__________________________________________________________________________________________________
conv3_1 (Conv2D)                (None, 24, 12, 192)  221376      concatenate_1[0][0]
__________________________________________________________________________________________________
conv3_2 (Conv2D)                (None, 24, 12, 193)  222529      concatenate_1[0][0]
__________________________________________________________________________________________________
conv4_1 (Conv2D)                (None, 24, 12, 192)  331968      conv3_1[0][0]
__________________________________________________________________________________________________
conv4_2 (Conv2D)                (None, 24, 12, 192)  333696      conv3_2[0][0]
__________________________________________________________________________________________________
conv5_1 (Conv2D)                (None, 24, 12, 128)  221312      conv4_1[0][0]
__________________________________________________________________________________________________
conv5_2 (Conv2D)                (None, 24, 12, 128)  221312      conv4_2[0][0]
__________________________________________________________________________________________________
pool5_1 (MaxPooling2D)          (None, 11, 5, 128)   0           conv5_1[0][0]
__________________________________________________________________________________________________
pool5_2 (MaxPooling2D)          (None, 11, 5, 128)   0           conv5_2[0][0]
__________________________________________________________________________________________________
concatenate_2 (Concatenate)     (None, 22, 5, 128)   0           pool5_1[0][0]
                                                                 pool5_2[0][0]
__________________________________________________________________________________________________
flatten (Flatten)               (None, 14080)        0           concatenate_2[0][0]
__________________________________________________________________________________________________
dense2_1 (Dense)                (None, 4096)         57675776    flatten[0][0]
__________________________________________________________________________________________________
dropout_1 (Dropout)             (None, 4096)         0           dense2_1[0][0]
__________________________________________________________________________________________________
dense3_1 (Dense)                (None, 4096)         16781312    dropout_1[0][0]
__________________________________________________________________________________________________
dropout_2 (Dropout)             (None, 4096)         0           dense3_1[0][0]
__________________________________________________________________________________________________
dense3_3 (Dense)                (None, 2)            8194        dropout_2[0][0]
__________________________________________________________________________________________________
softmax (Activation)            (None, 2)            0           dense3_3[0][0]
==================================================================================================
Total params: 76,359,875
Trainable params: 76,359,875
Non-trainable params: 0
__________________________________________________________________________________________________


到這裏模型定義完畢。

4、 將模型實例化,並編譯(compile) ,並開始訓練。

模型定義完成,使用簡單的語句實現編譯和訓練。
代碼段:

"""
編譯和訓練這個模型, 並保存模型。
"""
AlexNet = alex_net()

#檢查保存斷點文件夾是否存在,沒有的話就創建一個

if not os.path.exists('alex_net_checkpoints'):
	os.mkdir('alex_net_checkpoints')
	
#優化使用隨機梯度下降
sgd = SGD(lr = 0.01, decay = 1e-6, momentum = 0.9, nesterov = True)
#編譯網絡
AlexNet.compile(loss = 'categorical_crossentropy', optimizer = sgd, metrics = ['accuracy'])
#保存最優模型
checkpoint = ModelCheckpoint(monitor = 'val_acc', 
							filepath = "weights.best.hdf5",
							verbose = 1,
							mode = 'max',
							save_best_only = True)
							
							
#開始訓練網絡
AlexNet.fit(x_train, y_train, 
			batch_size = 64, 
			epochs = 5, 
			verbose = 1, 
			validation_data = (x_test, y_test),
			callbacks = [checkpoint]
			)
#打印測試集的精度和損失				
score = AlexNet.evaluate(x_test, y_test, verbose = 0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])

代碼中將開始訓練並且將最優模型保存爲hdf5文件(當預測時調用權重文件,進行預測)。
訓練效果:

Train on 500 samples, validate on 200 samples
Epoch 1/5
2019-05-27 16:46:15.490164: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX AVX2
500/500 [==============================] - 117s 234ms/step - loss: 0.6915 - acc: 0.5100 - val_loss: 0.6922 - val_acc: 0.5050

Epoch 00001: val_acc improved from -inf to 0.50500, saving model to weights.best.hdf5
Epoch 2/5
500/500 [==============================] - 115s 229ms/step - loss: 0.6951 - acc: 0.4940 - val_loss: 0.6907 - val_acc: 0.5000

Epoch 00002: val_acc did not improve from 0.50500
Epoch 3/5
500/500 [==============================] - 114s 228ms/step - loss: 0.6932 - acc: 0.5280 - val_loss: 0.6896 - val_acc: 0.5200

Epoch 00003: val_acc improved from 0.50500 to 0.52000, saving model to weights.best.hdf5
Epoch 4/5
500/500 [==============================] - 113s 227ms/step - loss: 0.6913 - acc: 0.5540 - val_loss: 0.6934 - val_acc: 0.5000

Epoch 00004: val_acc did not improve from 0.52000
Epoch 5/5
500/500 [==============================] - 117s 235ms/step - loss: 0.6975 - acc: 0.5080 - val_loss: 0.6887 - val_acc: 0.6300

Epoch 00005: val_acc improved from 0.52000 to 0.63000, saving model to weights.best.hdf5
Test loss: 0.6887068557739258
Test accuracy: 0.63

爲了節省時間,我將epoch改成了5。
由於我們使用的數據集很少,而且epoch不多(正常是80),訓練效果一般,但是實驗過程相同。

完整訓練代碼:

from keras import Model
from keras.callbacks import ModelCheckpoint
from keras.utils import to_categorical
from keras.layers import Flatten, Dense, Input
from keras.layers import Convolution2D, MaxPooling2D
from keras.preprocessing import image
from keras.layers.core import Dense, Dropout, Activation
from keras.layers import concatenate
import pandas
from keras.optimizers import SGD,Adam,RMSprop
from keras.optimizers import SGD
from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img
import numpy as np
import cv2
import os


IMG_CHANNELS=3 #PGB圖像爲三通道 R、G、B
#weight_decay = 0.0005 
IMG_ROWS=224  #圖像的行像素
IMG_COLS=224  #圖像的列像素
BATCH_SIZE=64 #batch大小
NB_EPOCH=10   #循環次數
NB_CLASSES=2  #分類  貓和狗兩種
VERBOSE=1
#VALIDATION_SPLIT=0.2
#OPTIM=RMSprop()
x_test=np.empty((200,IMG_ROWS,IMG_COLS,3),np.float16)  #測試集兩百張(200, 224, 224, 3)
x_train=np.empty((500,IMG_ROWS,IMG_COLS,3),np.float16)  #訓練集五百張(500, 224, 224, 3)
train_data=np.zeros(500)  #訓練集標籤
test_data=np.zeros(200)  #測試集標籤
#讀入訓練樣本
for i in range(500):
    if i<250:
		#載入250張貓
        train_data[i]=1#貓的標籤就是1
		#dog.8
        imagepath = "D:/python_pro/deep_learning_al/data/train/cats/cat." + str(i)+ ".jpg"#貓照片存儲路徑
        image1 = cv2.imread(imagepath)  #讀入文件
        image1 = cv2.cvtColor(image1, cv2.COLOR_BGR2RGB)  #轉爲RGB
        image1 = cv2.resize(image1,(IMG_ROWS,IMG_COLS))  #重新定義形狀爲(224, 224)
        #plt.imshow(image1)
        #plt.show()
        x_train[i,:,:,:]=image1   #訓練集矩陣,四維(500, 224, 224, 3)

    else:
		#載入250張狗
        train_data[i]=0#狗的標籤就是0
        imagepath = "D:/python_pro/deep_learning_al/data/train/dogs/dog." + str(i - 250)+ ".jpg" #狗照片路徑
        image1 = cv2.imread(imagepath)  #讀入文件
        image1 = cv2.cvtColor(image1, cv2.COLOR_BGR2RGB)#轉爲RGB
        image1 = cv2.resize(image1, (IMG_ROWS, IMG_COLS))#重新定義形狀爲(224, 224)
        x_train[i, :, :, :] = image1 #訓練集矩陣,四維(500, 224, 224, 3)
y_train=to_categorical(train_data) #訓練集標籤(500, 2)
x_train=np.array(x_train)  #完整訓練集矩陣
#讀入測試樣本
for i in range(200):
    if i<100:
		#載入100張貓
        test_data[i]=1#貓的標籤就是1
        imagepath =  "D:/python_pro/deep_learning_al/data/test/cats/cat."+str(i+250)+'.jpg'#貓照片存儲路徑
        image1 = cv2.imread(imagepath)#讀入文件
        image1 = cv2.cvtColor(image1, cv2.COLOR_BGR2RGB)#轉爲RGB
        image1 = cv2.resize(image1,(IMG_ROWS,IMG_COLS)) #重新定義形狀爲(224, 224)
        x_test[i,:,:,:]=image1

    else:
		#載入100張狗
        test_data[i]=0#狗的標籤就是0
        imagepath=  "D:/python_pro/deep_learning_al/data/test/dogs/dog."+str(i+250-100)+'.jpg'#狗照片路徑
        image1 = cv2.imread(imagepath)#讀入文件
        image1 = cv2.cvtColor(image1, cv2.COLOR_BGR2RGB)#轉爲RGB
        image1 = cv2.resize(image1, (IMG_ROWS, IMG_COLS))#重新定義形狀爲(224, 224)
        x_test[i, :, :, :] = image1
y_test=to_categorical(test_data) #測試集標籤(200, 2)
#print(sys.getsizeof(x_test),sys.getsizeof(y_test))
x_test=np.array(x_test) #完整測試集矩陣(200, 224, 224, 3)
#歸一化
#x_train.shape = (500, 224, 224, 3)
#x_test.shape = (200, 224, 224, 3)
x_train=x_train/255  #像素是8位的,所以0-255編程0-1除以255即可。
x_test = x_test/255

print(x_train.shape,x_test.shape,y_train.shape,y_test.shape)
# #數據多樣化

# batch_size = 16

# train_datagen = ImageDataGenerator(
        # rescale=1./255,
        # shear_range=0.2,
        # zoom_range=0.2,
        # horizontal_flip=True)

# test_datagen = ImageDataGenerator(rescale=1./255)

# train_generator = train_datagen.flow_from_directory(
        # 'D:\python項目\deep_learning_al\train1', 
        # target_size=(224, 224),  
        # batch_size=batch_size,
        # class_mode='categorical')

# validation_generator = test_datagen.flow_from_directory(
        # 'D:\python項目\deep_learning_al\validation',
        # target_size=(224, 224),
        # batch_size=batch_size,
        # class_mode='categorical')	
		
		
		
input_shape = (224, 224, 3)

"""
創建alexnet網絡模型
"""

#分類數量
nb_classes = 2
def alex_net(w_path = None):
	#輸入圖像爲(3, 224, 224)
	input_shape = (224, 224, 3)
	#輸入層
	inputs = Input(shape = input_shape, name = 'input')

	#第一層:兩個卷積操作和兩個pooling操作

	conv1_1 = Convolution2D(48, (11, 11), strides = (4, 4), activation = 'relu', name = 'conv1_1')(inputs)
	conv1_2 = Convolution2D(48, (11, 11), strides = (4, 4), activation = 'relu', name = 'conv1_2')(inputs)

	pool1_1 = MaxPooling2D((3, 3), strides = (2, 2), name = 'pool1_1')(conv1_1)
	pool1_2 = MaxPooling2D((3, 3), strides = (2, 2), name = 'pool1_2')(conv1_2)

	#layer2:兩個卷積,將前邊的池化得到的數據,進行卷積,再繼續池化

	conv2_1 = Convolution2D(128, (5, 5), activation = 'relu', padding = 'same')(pool1_1)
	conv2_2 = Convolution2D(128, (5, 5), activation = 'relu', padding = 'same')(pool1_2)

	pool2_1 = MaxPooling2D((3, 3), strides = (2, 2), name = 'pool2_1')(conv2_1)
	pool2_2 = MaxPooling2D((3, 3), strides = (2, 2), name = 'pool2_2')(conv2_2)

	#merge合併層:第二層進入第三層,將數據混合合併
	merge1 = concatenate([pool2_2, pool2_1], axis = 1)

	#layer3:兩個卷積操作

	conv3_1 = Convolution2D(192, (3, 3), activation = 'relu', name = 'conv3_1', padding = 'same')(merge1)
	conv3_2 = Convolution2D(193, (3, 3), activation = 'relu', name = 'conv3_2', padding = 'same')(merge1)

	#latyer4:兩個卷積操作
	conv4_1 = Convolution2D(192, (3, 3), activation = 'relu', name = 'conv4_1', padding = 'same')(conv3_1)
	conv4_2 = Convolution2D(192, (3, 3), activation = 'relu', name = 'conv4_2', padding = 'same')(conv3_2)

	#layer5:兩個卷積操作和兩個pooling操作
	conv5_1 = Convolution2D(128, (3, 3), activation = 'relu', name = 'conv5_1', padding = 'same')(conv4_1)
	conv5_2 = Convolution2D(128, (3, 3), activation = 'relu', name = 'conv5_2', padding = 'same')(conv4_2)

	pool5_1 = MaxPooling2D((3, 3), strides = (2, 2), name = 'pool5_1')(conv5_1)
	pool5_2 = MaxPooling2D((3, 3), strides = (2, 2), name = 'pool5_2')(conv5_2)

	#merge合併層:第五層進入全連接之前,要將分開的合併
	merge2 = concatenate([pool5_1, pool5_2], axis = 1)

	#通過flatten將多維輸入一維化
	dense1 = Flatten(name = 'flatten')(merge2)

	#layer6, layer7 第六,七層, 進行兩次4096維的全連接,中間加dropout避免過擬合
	dense2_1 = Dense(4096, activation = 'relu', name = 'dense2_1')(dense1)
	dense2_2 = Dropout(0.5)(dense2_1)

	dense3_1 = Dense(4096, activation = 'relu', name = 'dense3_1')(dense2_2)
	dense3_2 = Dropout(0.5)(dense3_1)

	#輸出層:輸出類別,分類函數使用softmax

	dense3_3 = Dense(nb_classes, name = 'dense3_3')(dense3_2)
	prediction = Activation('softmax', name = 'softmax')(dense3_3)
	

	#最後定義模型輸出
	AlexNet = Model(input = inputs, outputs = prediction)
	if(w_path):
		#加載權重數據
		AlexNet.load_weights(w_path)
		
	return AlexNet	
#AlexNet.summary()

"""
編譯和訓練這個模型
"""
AlexNet = alex_net()

#檢查保存斷點文件夾是否存在,沒有的話就創建一個

if not os.path.exists('alex_net_checkpoints'):
	os.mkdir('alex_net_checkpoints')
	
#優化使用隨機梯度下降
sgd = SGD(lr = 0.01, decay = 1e-6, momentum = 0.9, nesterov = True)
AlexNet.compile(loss = 'categorical_crossentropy', optimizer = sgd, metrics = ['accuracy'])

checkpoint = ModelCheckpoint(monitor = 'val_acc', 
							filepath = "weights.best.hdf5",
							verbose = 1,
							mode = 'max',
							save_best_only = True)
							
							
#開始訓練網絡
AlexNet.fit(x_train, y_train, 
			batch_size = 64, 
			epochs = 5, 
			verbose = 1, 
			validation_data = (x_test, y_test),
			callbacks = [checkpoint]
			)
				
score = AlexNet.evaluate(x_test, y_test, verbose = 0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])
# #訓練模型,訓練結果保存在history-callback中
# history_callback = AlexNet.fit_generator(
										# train_generator,
										# steps_per_epoch = 2000,
										# epochs = 80,
										# validation_data = validation_generator,
										# validation_steps = 800
										# )
										
# #訓練完存儲訓練的結果和模型中的權重參數
# pandas.DataFrame(history_callback.history).to_csv('.\AlexNet_model.csv')
# AlexNet.save_weights('.\AlexNet_model.h5')
	

5、預測

  • 加載權重文件和待預測圖像,開始預測。
  • 只要將保存好的模型加載,並對待預測圖片進行一次正向傳播,就可以預測出結果。
    代碼段:
#對模型做出預測
AlexNet.load_weights('D:/python_pro/deep_learning_al/weights.best.hdf5')	#加載權重文件
img_path =  "D:/python_pro/deep_learning_al/data/80.jpg"  #待預測圖片的路徑
img = image.load_img(img_path, target_size = input_shape[0:]) #加載圖像
x = image.img_to_array(img) #  轉換爲二維數組形式
x = np.expand_dims(x, axis = 0) #擴展圖像維度爲(1, 224, 224, 3)
x = x.reshape((-1, ) + input_shape) / 255 #歸一化

pres = AlexNet.predict(x)
print(pres)

預測結果:

predict.py:86: UserWarning: Update your `Model` call to the Keras 2 API: `Model(outputs=Tensor("so..., inputs=Tensor("in...)`
  AlexNet = Model(input = inputs, outputs = prediction)
2019-05-27 17:25:24.061630: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX AVX2
[[0.5057532 0.4942468]]

80.jpg是狗狗,0代表狗, 1代表貓。勉強能看出是狗…,雖然效果不好,但是流程就是這樣!改模型,增加數據集,增加epoch,改loss,改優化函數,加Drop out 等等吧就能可能得到不錯的效果,參數的更改和模型的使用更多的還是經驗。

完整預測代碼:

from keras import Model
from keras.callbacks import ModelCheckpoint
from keras.utils import to_categorical
from keras.layers import Flatten, Dense, Input
from keras.layers import Convolution2D, MaxPooling2D
from keras.preprocessing import image
from keras.layers.core import Dense, Dropout, Activation
from keras.layers import concatenate
import pandas
from keras.optimizers import SGD,Adam,RMSprop
from keras.optimizers import SGD
from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img
import numpy as np
import cv2
import os

input_shape = (224, 224, 3)

"""
創建alexnet網絡模型
"""

#分類數量
nb_classes = 2
def alex_net(w_path = None):
	#輸入圖像爲(3, 227, 227)
	input_shape = (224, 224, 3)
	#輸入層
	inputs = Input(shape = input_shape, name = 'input')

	#第一層:兩個卷積操作和兩個pooling操作

	conv1_1 = Convolution2D(48, (11, 11), strides = (4, 4), activation = 'relu', name = 'conv1_1')(inputs)
	conv1_2 = Convolution2D(48, (11, 11), strides = (4, 4), activation = 'relu', name = 'conv1_2')(inputs)

	pool1_1 = MaxPooling2D((3, 3), strides = (2, 2), name = 'pool1_1')(conv1_1)
	pool1_2 = MaxPooling2D((3, 3), strides = (2, 2), name = 'pool1_2')(conv1_2)

	#layer2:兩個卷積,將前邊的池化得到的數據,進行卷積,再繼續池化

	conv2_1 = Convolution2D(128, (5, 5), activation = 'relu', padding = 'same')(pool1_1)
	conv2_2 = Convolution2D(128, (5, 5), activation = 'relu', padding = 'same')(pool1_2)

	pool2_1 = MaxPooling2D((3, 3), strides = (2, 2), name = 'pool2_1')(conv2_1)
	pool2_2 = MaxPooling2D((3, 3), strides = (2, 2), name = 'pool2_2')(conv2_2)

	#merge合併層:第二層進入第三層,將數據混合合併
	merge1 = concatenate([pool2_2, pool2_1], axis = 1)

	#layer3:兩個卷積操作

	conv3_1 = Convolution2D(192, (3, 3), activation = 'relu', name = 'conv3_1', padding = 'same')(merge1)
	conv3_2 = Convolution2D(193, (3, 3), activation = 'relu', name = 'conv3_2', padding = 'same')(merge1)

	#latyer4:兩個卷積操作
	conv4_1 = Convolution2D(192, (3, 3), activation = 'relu', name = 'conv4_1', padding = 'same')(conv3_1)
	conv4_2 = Convolution2D(192, (3, 3), activation = 'relu', name = 'conv4_2', padding = 'same')(conv3_2)

	#layer5:兩個卷積操作和兩個pooling操作
	conv5_1 = Convolution2D(128, (3, 3), activation = 'relu', name = 'conv5_1', padding = 'same')(conv4_1)
	conv5_2 = Convolution2D(128, (3, 3), activation = 'relu', name = 'conv5_2', padding = 'same')(conv4_2)

	pool5_1 = MaxPooling2D((3, 3), strides = (2, 2), name = 'pool5_1')(conv5_1)
	pool5_2 = MaxPooling2D((3, 3), strides = (2, 2), name = 'pool5_2')(conv5_2)

	#merge合併層:第五層進入全連接之前,要將分開的合併
	merge2 = concatenate([pool5_1, pool5_2], axis = 1)

	#通過flatten將多維輸入一維化
	dense1 = Flatten(name = 'flatten')(merge2)

	#layer6, layer7 第六,七層, 進行兩次4096維的全連接,中間加dropout避免過擬合
	dense2_1 = Dense(4096, activation = 'relu', name = 'dense2_1')(dense1)
	dense2_2 = Dropout(0.5)(dense2_1)

	dense3_1 = Dense(4096, activation = 'relu', name = 'dense3_1')(dense2_2)
	dense3_2 = Dropout(0.5)(dense3_1)

	#輸出層:輸出類別,分類函數使用softmax

	dense3_3 = Dense(nb_classes, name = 'dense3_3')(dense3_2)
	prediction = Activation('softmax', name = 'softmax')(dense3_3)
	

	#最後定義模型輸出
	AlexNet = Model(input = inputs, outputs = prediction)
	if(w_path):
		#加載權重數據
		AlexNet.load_weights(w_path)
		
	return AlexNet	
AlexNet = alex_net()
#優化使用隨機梯度下降
sgd = SGD(lr = 0.01, decay = 1e-6, momentum = 0.9, nesterov = True)
AlexNet.compile(loss = 'categorical_crossentropy', optimizer = sgd, metrics = ['accuracy'])

#對模型做出預測
AlexNet.load_weights('D:/python_pro/deep_learning_al/weights.best.hdf5')	#加載權重文件
img_path =  "D:/python_pro/deep_learning_al/data/80.jpg"  #待預測圖片的路徑
img = image.load_img(img_path, target_size = input_shape[0:]) #加載圖像
x = image.img_to_array(img) #  轉換爲二維數組形式
x = np.expand_dims(x, axis = 0) #擴展圖像維度爲(1, 224, 224, 3)
x = x.reshape((-1, ) + input_shape) / 255 #歸一化

pres = AlexNet.predict(x)
print(pres)

6、微調網絡

神經網絡的訓練精度一般,我們可以考慮爲微調網絡,本次實驗僅僅對不同層的學習率進行了更改。
代碼段1:數據生成器

datagen = ImageDataGenerator(
    featurewise_center=True,
    featurewise_std_normalization=True,
    rotation_range=20,
    width_shift_range=0.2,
    height_shift_range=0.2,
    horizontal_flip=True)

datagen.fit(x_train)

代碼段2:

#微調網絡
#定義需要重新訓練的網絡層
layers = ['dense3_3', 'dense3_1', 'dense2_2', 'pool5_1', 
			'conv4_1', 'conv3_1', 'conv2_1', 'conv1_1'
			
		]
#對重新訓練的網絡層迭代次數
epochs = [1, 1, 1, 1, 1, 1,1, 1]

#重新定義的網絡層隨機梯度下降的學習率
lr = [1e-2, 1e-3, 1e-4, 1e-4,  1e-4,  1e-4,  1e-4, 1e-4]

#開始迭代需要重新訓練的網絡層
for i, layer in enumerate(layers):
	#標記指定layer是可訓練的層
	for layer in AlexNet.layers:
		if layer.name == layer:
			layer.trainable = True
		layer.trainable = False  #其餘的層凍結,不能夠訓練
		
	#編譯該層網絡的權重參數
	sgd = SGD(lr = lr[i], decay = 1e-6, momentum = 0.9, nesterov = True)
	AlexNet.compile(loss = 'categorical_crossentropy', optimizer = sgd, metrics = ['accuracy'])
		
		
	#訓練該層網絡的權重參數,每層迭代epoch[i]次
	for epoch in range(epochs[i]):
	# history = AlexNet.fit_generator(
									# x_train,
									# #steps_per_epoch = None,
									# epochs = 1,
									# validation_data = x_test,
									# #validation_steps = None
									# )
									
		AlexNet.fit_generator(datagen.flow(x_train, y_train, batch_size=32),
						steps_per_epoch=len(x_train) / 32, epochs=2)
									
#存儲fine_tune後的權重參數
AlexNet.save_weights('weights1.h5')

完整代碼段:

from keras import Model
from keras.callbacks import ModelCheckpoint
from keras.utils import to_categorical
from keras.layers import Flatten, Dense, Input
from keras.layers import Convolution2D, MaxPooling2D
from keras.preprocessing import image
from keras.layers.core import Dense, Dropout, Activation
from keras.layers import concatenate
import pandas
from keras.optimizers import SGD,Adam,RMSprop
from keras.optimizers import SGD
from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img
import numpy as np
import cv2
import os


IMG_CHANNELS=3 #PGB圖像爲三通道 R、G、B
#weight_decay = 0.0005 
IMG_ROWS=224  #圖像的行像素
IMG_COLS=224  #圖像的列像素
BATCH_SIZE=64 #batch大小
NB_EPOCH=10   #循環次數
NB_CLASSES=2  #分類  貓和狗兩種
VERBOSE=1
#VALIDATION_SPLIT=0.2
#OPTIM=RMSprop()
x_test=np.empty((200,IMG_ROWS,IMG_COLS,3),np.float16)  #測試集兩百張(200, 224, 224, 3)
x_train=np.empty((500,IMG_ROWS,IMG_COLS,3),np.float16)  #訓練集五百張(500, 224, 224, 3)
train_data=np.zeros(500)  #訓練集標籤
test_data=np.zeros(200)  #測試集標籤
#讀入訓練樣本
for i in range(500):
    if i<250:
		#載入250張貓
        train_data[i]=1#貓的標籤就是1
		#dog.8
        imagepath = "D:/python_pro/deep_learning_al/data/train/cats/cat." + str(i)+ ".jpg"#貓照片存儲路徑
        image1 = cv2.imread(imagepath)  #讀入文件
        image1 = cv2.cvtColor(image1, cv2.COLOR_BGR2RGB)  #轉爲RGB
        image1 = cv2.resize(image1,(IMG_ROWS,IMG_COLS))  #重新定義形狀爲(224, 224)
        #plt.imshow(image1)
        #plt.show()
        x_train[i,:,:,:]=image1   #訓練集矩陣,四維(500, 224, 224, 3)

    else:
		#載入250張狗
        train_data[i]=0#狗的標籤就是0
        imagepath = "D:/python_pro/deep_learning_al/data/train/dogs/dog." + str(i - 250)+ ".jpg" #狗照片路徑
        image1 = cv2.imread(imagepath)  #讀入文件
        image1 = cv2.cvtColor(image1, cv2.COLOR_BGR2RGB)#轉爲RGB
        image1 = cv2.resize(image1, (IMG_ROWS, IMG_COLS))#重新定義形狀爲(224, 224)
        x_train[i, :, :, :] = image1 #訓練集矩陣,四維(500, 224, 224, 3)
y_train=to_categorical(train_data) #訓練集標籤(500, 2)
x_train=np.array(x_train)  #完整訓練集矩陣
#讀入測試樣本
for i in range(200):
    if i<100:
		#載入100張貓
        test_data[i]=1#貓的標籤就是1
        imagepath =  "D:/python_pro/deep_learning_al/data/test/cats/cat."+str(i+250)+'.jpg'#貓照片存儲路徑
        image1 = cv2.imread(imagepath)#讀入文件
        image1 = cv2.cvtColor(image1, cv2.COLOR_BGR2RGB)#轉爲RGB
        image1 = cv2.resize(image1,(IMG_ROWS,IMG_COLS)) #重新定義形狀爲(224, 224)
        x_test[i,:,:,:]=image1

    else:
		#載入100張狗
        test_data[i]=0#狗的標籤就是0
        imagepath=  "D:/python_pro/deep_learning_al/data/test/dogs/dog."+str(i+250-100)+'.jpg'#狗照片路徑
        image1 = cv2.imread(imagepath)#讀入文件
        image1 = cv2.cvtColor(image1, cv2.COLOR_BGR2RGB)#轉爲RGB
        image1 = cv2.resize(image1, (IMG_ROWS, IMG_COLS))#重新定義形狀爲(224, 224)
        x_test[i, :, :, :] = image1
y_test=to_categorical(test_data) #測試集標籤(200, 2)
#print(sys.getsizeof(x_test),sys.getsizeof(y_test))
x_test=np.array(x_test) #完整測試集矩陣(200, 224, 224, 3)
#歸一化
#x_train.shape = (500, 224, 224, 3)
#x_test.shape = (200, 224, 224, 3)
x_train=x_train/255  #像素是8位的,所以0-255編程0-1除以255即可。
x_test = x_test/255

print(x_train.shape,x_test.shape,y_train.shape,y_test.shape)

datagen = ImageDataGenerator(
    featurewise_center=True,
    featurewise_std_normalization=True,
    rotation_range=20,
    width_shift_range=0.2,
    height_shift_range=0.2,
    horizontal_flip=True)

datagen.fit(x_train)


# #數據多樣化

# batch_size = 16

# train_datagen = ImageDataGenerator(
        # rescale=1./255,
        # shear_range=0.2,
        # zoom_range=0.2,
        # horizontal_flip=True)

# test_datagen = ImageDataGenerator(rescale=1./255)

# train_generator = train_datagen.flow_from_directory(
        # 'D:\python項目\deep_learning_al\train1', 
        # target_size=(224, 224),  
        # batch_size=batch_size,
        # class_mode='categorical')

# validation_generator = test_datagen.flow_from_directory(
        # 'D:\python項目\deep_learning_al\validation',
        # target_size=(224, 224),
        # batch_size=batch_size,
        # class_mode='categorical')	
		
		
		
input_shape = (224, 224, 3)

"""
創建alexnet網絡模型
"""

#分類數量
nb_classes = 2
def alex_net(w_path = None):
	#輸入圖像爲(3, 224, 224)
	input_shape = (224, 224, 3)
	#輸入層
	inputs = Input(shape = input_shape, name = 'input')

	#第一層:兩個卷積操作和兩個pooling操作

	conv1_1 = Convolution2D(48, (11, 11), strides = (4, 4), activation = 'relu', name = 'conv1_1')(inputs)
	conv1_2 = Convolution2D(48, (11, 11), strides = (4, 4), activation = 'relu', name = 'conv1_2')(inputs)

	pool1_1 = MaxPooling2D((3, 3), strides = (2, 2), name = 'pool1_1')(conv1_1)
	pool1_2 = MaxPooling2D((3, 3), strides = (2, 2), name = 'pool1_2')(conv1_2)

	#layer2:兩個卷積,將前邊的池化得到的數據,進行卷積,再繼續池化

	conv2_1 = Convolution2D(128, (5, 5), activation = 'relu', padding = 'same')(pool1_1)
	conv2_2 = Convolution2D(128, (5, 5), activation = 'relu', padding = 'same')(pool1_2)

	pool2_1 = MaxPooling2D((3, 3), strides = (2, 2), name = 'pool2_1')(conv2_1)
	pool2_2 = MaxPooling2D((3, 3), strides = (2, 2), name = 'pool2_2')(conv2_2)

	#merge合併層:第二層進入第三層,將數據混合合併
	merge1 = concatenate([pool2_2, pool2_1], axis = 1)

	#layer3:兩個卷積操作

	conv3_1 = Convolution2D(192, (3, 3), activation = 'relu', name = 'conv3_1', padding = 'same')(merge1)
	conv3_2 = Convolution2D(193, (3, 3), activation = 'relu', name = 'conv3_2', padding = 'same')(merge1)

	#latyer4:兩個卷積操作
	conv4_1 = Convolution2D(192, (3, 3), activation = 'relu', name = 'conv4_1', padding = 'same')(conv3_1)
	conv4_2 = Convolution2D(192, (3, 3), activation = 'relu', name = 'conv4_2', padding = 'same')(conv3_2)

	#layer5:兩個卷積操作和兩個pooling操作
	conv5_1 = Convolution2D(128, (3, 3), activation = 'relu', name = 'conv5_1', padding = 'same')(conv4_1)
	conv5_2 = Convolution2D(128, (3, 3), activation = 'relu', name = 'conv5_2', padding = 'same')(conv4_2)

	pool5_1 = MaxPooling2D((3, 3), strides = (2, 2), name = 'pool5_1')(conv5_1)
	pool5_2 = MaxPooling2D((3, 3), strides = (2, 2), name = 'pool5_2')(conv5_2)

	#merge合併層:第五層進入全連接之前,要將分開的合併
	merge2 = concatenate([pool5_1, pool5_2], axis = 1)

	#通過flatten將多維輸入一維化
	dense1 = Flatten(name = 'flatten')(merge2)

	#layer6, layer7 第六,七層, 進行兩次4096維的全連接,中間加dropout避免過擬合
	dense2_1 = Dense(4096, activation = 'relu', name = 'dense2_1')(dense1)
	dense2_2 = Dropout(0.5)(dense2_1)

	dense3_1 = Dense(4096, activation = 'relu', name = 'dense3_1')(dense2_2)
	dense3_2 = Dropout(0.5)(dense3_1)

	#輸出層:輸出類別,分類函數使用softmax

	dense3_3 = Dense(nb_classes, name = 'dense3_3')(dense3_2)
	prediction = Activation('softmax', name = 'softmax')(dense3_3)
	

	#最後定義模型輸出
	AlexNet = Model(input = inputs, outputs = prediction)
	if(w_path):
		#加載權重數據
		AlexNet.load_weights(w_path)
		
	return AlexNet	
#AlexNet.summary()

"""
編譯和訓練這個模型
"""
AlexNet = alex_net()

# #檢查保存斷點文件夾是否存在,沒有的話就創建一個

# if not os.path.exists('alex_net_checkpoints'):
	# os.mkdir('alex_net_checkpoints')
	
#微調網絡
#定義需要重新訓練的網絡層
layers = ['dense3_3', 'dense3_1', 'dense2_2', 'pool5_1', 
			'conv4_1', 'conv3_1', 'conv2_1', 'conv1_1'
			
		]
#對重新訓練的網絡層迭代次數
epochs = [1, 1, 1, 1, 1, 1,1, 1]

#重新定義的網絡層隨機梯度下降的學習率
lr = [1e-2, 1e-3, 1e-4, 1e-4,  1e-4,  1e-4,  1e-4, 1e-4]

#開始迭代需要重新訓練的網絡層
for i, layer in enumerate(layers):
	#標記指定layer是可訓練的層
	for layer in AlexNet.layers:
		if layer.name == layer:
			layer.trainable = True
		layer.trainable = False  #其餘的層凍結,不能夠訓練
		
	#編譯該層網絡的權重參數
	sgd = SGD(lr = lr[i], decay = 1e-6, momentum = 0.9, nesterov = True)
	AlexNet.compile(loss = 'categorical_crossentropy', optimizer = sgd, metrics = ['accuracy'])
		
		
	#訓練該層網絡的權重參數,每層迭代epoch[i]次
	for epoch in range(epochs[i]):
	# history = AlexNet.fit_generator(
									# x_train,
									# #steps_per_epoch = None,
									# epochs = 1,
									# validation_data = x_test,
									# #validation_steps = None
									# )
									
		AlexNet.fit_generator(datagen.flow(x_train, y_train, batch_size=32),
						steps_per_epoch=len(x_train) / 32, epochs=2)
									
#存儲fine_tune後的權重參數
AlexNet.save_weights('weights1.h5')
# #優化使用隨機梯度下降
# sgd = SGD(lr = 0.01, decay = 1e-6, momentum = 0.9, nesterov = True)
# AlexNet.compile(loss = 'categorical_crossentropy', optimizer = sgd, metrics = ['accuracy'])

# checkpoint = ModelCheckpoint(monitor = 'val_acc', 
							# # filepath = "weights.best.hdf5",
							# # verbose = 1,
							# # mode = 'max',
							# # save_best_only = True)
							
							
# #開始訓練網絡
# AlexNet.fit(x_train, y_train, 
			# batch_size = 64, 
			# epochs = 5, 
			# verbose = 1, 
			# validation_data = (x_test, y_test),
			# callbacks = [checkpoint]
			# )
				
# score = AlexNet.evaluate(x_test, y_test, verbose = 0)
# print('Test loss:', score[0])
# print('Test accuracy:', score[1])
# # #訓練模型,訓練結果保存在history-callback中
# # history_callback = AlexNet.fit_generator(
										# train_generator,
										# steps_per_epoch = 2000,
										# epochs = 80,
										# validation_data = validation_generator,
										# validation_steps = 800
										# )
										
# #訓練完存儲訓練的結果和模型中的權重參數
# pandas.DataFrame(history_callback.history).to_csv('.\AlexNet_model.csv')
# AlexNet.save_weights('.\AlexNet_model.h5')

微調效果:

 AlexNet = Model(input = inputs, outputs = prediction)
Epoch 1/2
2019-05-28 14:31:46.084488: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX AVX2
16/15 [==============================] - 43s 3s/step - loss: 0.6985 - acc: 0.4818
Epoch 2/2
16/15 [==============================] - 39s 2s/step - loss: 0.6902 - acc: 0.5282
Epoch 1/2
16/15 [==============================] - 42s 3s/step - loss: 0.6914 - acc: 0.5522
Epoch 2/2
16/15 [==============================] - 39s 2s/step - loss: 0.6975 - acc: 0.5308
Epoch 1/2
16/15 [==============================] - 42s 3s/step - loss: 0.6930 - acc: 0.5139
Epoch 2/2
16/15 [==============================] - 39s 2s/step - loss: 0.7016 - acc: 0.4972
Epoch 1/2
16/15 [==============================] - 42s 3s/step - loss: 0.7037 - acc: 0.4830
Epoch 2/2
16/15 [==============================] - 39s 2s/step - loss: 0.6950 - acc: 0.5229
Epoch 1/2
16/15 [==============================] - 42s 3s/step - loss: 0.6974 - acc: 0.5000
Epoch 2/2
16/15 [==============================] - 39s 2s/step - loss: 0.6979 - acc: 0.5237
Epoch 1/2
16/15 [==============================] - 41s 3s/step - loss: 0.6949 - acc: 0.5156
Epoch 2/2
16/15 [==============================] - 39s 2s/step - loss: 0.7011 - acc: 0.5000
Epoch 1/2
16/15 [==============================] - 42s 3s/step - loss: 0.6912 - acc: 0.4972
Epoch 2/2
16/15 [==============================] - 39s 2s/step - loss: 0.6988 - acc: 0.4813
Epoch 1/2
16/15 [==============================] - 42s 3s/step - loss: 0.6874 - acc: 0.5394
Epoch 2/2
16/15 [==============================] - 39s 2s/step - loss: 0.6955 - acc: 0.5193

模型微調之後,重新存儲模型文件,然後利用新的權重文件進行預測。

這裏邊沒有用到預訓練模型,以後可能還會遇到的.

這篇文章主要是對自己的實驗流程做個總結,同時希望對喜歡深度學習的你帶來幫助,謝謝!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章