05 TensorFlow 2.0:CNN總結及實戰

浮雲愛蹉跎 流光怕寂寞
填殘篇脈絡 續斷章因果
問今生旅途幾時交錯
前塵燈火 隔世傳說
                                                                                                                                《流光卷》

卷積層

發現特徵輪廓,實現特徵提取。數據稀疏交互,參數共享(因爲樣本存在局部相關的特性),參數大幅下降。爲了保證輸入輸出shape一致,可採用padding。深層,習得更高級的特徵。

激活層

卷積層發現特徵之後,激活層,有種使得重要特徵更突出,不重要特徵爲0或者更小的意思(Relu負的值=0)。還有一種解釋是,非線性變換,空間維度扭曲,這樣就可以在高維表徵/區分數據特徵。

池化層

下采樣,一般2x2的過濾器maxpooling,4個點變1個,最大特徵凸顯,減少卷積核尺寸(長度和寬度改變了,深度沒變),權重參數的數目減少到了75%。一定程度提高空間不變性,比如說平移不變性,尺度不變性,形變不變性(降採樣特性),控制過擬合。

全連接層

對學習到的特徵進行結果的概率映射(多分類softmax保證輸出P爲0~1且概率和=1)。也就是這裏解釋說的“分類器”作用。因全連接大幅增加了參數,目前有用其他代替全連接的策略,可搜搜。

動手搭建一個

CIFAR-100數據集CNN搭建

import tensorflow as tf
import getConfig
gConfig={}
gConfig=getConfig.get_config(config_file='config.ini')

class cnnModel(object):
    #初始化函數,將dropout的失效概率初始化
    def __init__(self,rate):
        self.rate=rate
    def createModel(self):
        #容器
        model = tf.keras.Sequential()
        #使用雙層卷積結構的方式提取圖像特徵,第一層雙層卷積使用使用3*3的卷積核,輸出維度是64,全局使用he_normal進行kernel_initializer,激活函數使用relu
        model.add(tf.keras.layers.Conv2D(64, 3, kernel_initializer='he_normal', strides=1, activation='relu', padding='same',input_shape=(32,32,3),name="conv1"))
        model.add(tf.keras.layers.Conv2D(64, 3, kernel_initializer='he_normal', strides=1, activation='relu', padding='same',
                                    name="conv2"))
        #使用tf.keras.layers.MaxPool2D搭建神經網絡的池化層,使用最大值池化策略,將2*2局域的像素使用一個最大值代替,步幅爲2,padding使用valid策略
        model.add(tf.keras.layers.MaxPool2D((2, 2), strides=2, padding='valid', name="pool1"))
        #疊加一層Dropout層,提高泛化性,降低神經網絡的複雜度
        model.add(tf.keras.layers.Dropout(rate=self.rate, name="d1"))
        # 使用batchnormalization對上一層的輸出數據進行歸一化
        model.add(tf.keras.layers.BatchNormalization())
        # 使用雙層卷積結構的方式提取圖像特徵,第二層雙層卷積使用使用3*3的卷積核,輸出維度是128,全局使用he_normal進行kernel_initializer,激活函數使用relu
        model.add(tf.keras.layers.Conv2D(128, 3, kernel_initializer='he_normal', strides=1, activation='relu', padding='same',
                                   name="conv3"))
        model.add(tf.keras.layers.Conv2D(128, 3, kernel_initializer='he_normal', strides=1, activation='relu', padding='same',
                                    name="conv4"))
        # 使用tf.keras.layers.MaxPool2D搭建神經網絡的池化層,使用最大值池化策略,將2*2局域的像素使用一個最大值代替,步幅爲2,padding使用valid策略
        model.add(tf.keras.layers.MaxPool2D((2, 2), strides=2, padding='valid', name="pool2"))
        # 疊加一層Dropout層,提高泛化性,降低神經網絡的複雜度
        model.add(tf.keras.layers.Dropout(rate=self.rate, name="d2"))
        # 使用batchnormalization對上一層的輸出數據進行歸一化
        model.add(tf.keras.layers.BatchNormalization())
        # 使用雙層卷積結構的方式提取圖像特徵,第三層雙層卷積使用使用3*3的卷積核,輸出維度是128,全局使用he_normal進行kernel_initializer,激活函數使用relu
        model.add(tf.keras.layers.Conv2D(256, 3, kernel_initializer='he_normal', strides=1, activation='relu', padding='same',
                                   name="conv5"))
        model.add(tf.keras.layers.Conv2D(256, 3, kernel_initializer='he_normal', strides=1, activation='relu', padding='same',
                                   name="conv6"))
        # 使用tf.keras.layers.MaxPool2D搭建神經網絡的池化層,使用最大值池化策略,將2*2局域的像素使用一個最大值代替,步幅爲2,padding使用valid策略
        model.add(tf.keras.layers.MaxPool2D((2, 2), strides=2, padding='valid', name="pool3"))
        # 疊加一層Dropout層,提高泛化性,降低神經網絡的複雜度
        model.add(tf.keras.layers.Dropout(rate=self.rate, name="d3"))
        # 使用batchnormalization對上一層的輸出數據進行歸一化
        model.add(tf.keras.layers.BatchNormalization())
        # 使用flatten將上層的輸出數據壓平
        model.add(tf.keras.layers.Flatten(name="flatten"))
        # 疊加一層Dropout層,提高泛化性,降低神經網絡的複雜度
        model.add(tf.keras.layers.Dropout(self.rate))
        # 疊加一層全連接層,用於擬合最終結果,激活函數使用relu
        model.add(tf.keras.layers.Dense(128, activation='relu',kernel_initializer='he_normal'))
        # 疊加一層Dropout層,提高泛化性,降低神經網絡的複雜度
        model.add(tf.keras.layers.Dropout(self.rate))
        # 疊加一層全連接層作爲輸出層,激活函數使用softmax
        model.add(tf.keras.layers.Dense(100, activation='softmax',kernel_initializer='he_normal'))
        #最後編譯搭建完成的神經網絡,使用categorical_crossentropy損失函數,adam優化器,模型的衡量指標是準確率
        model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
        #返回編譯完成的model
        return model

config設置

[strings]
# Mode : train, test, serve
mode = train
working_directory = model_dir
dataset_path=.../DL/CIFAR_100_homework/train_data/
test_path=.../DL/CIFAR_100_homework/test_data/

[ints]
steps_per_checkpoint = 2
num_dataset_classes=100
dataset_size=50000
im_dim=32
num_channels = 3
num_files=1
images_per_file=10000
epochs=2
[floats]
keeps=0.5

get_config

import configparser
def get_config(config_file='config.ini'):
    parser=configparser.ConfigParser()
    parser.read(config_file)
    # get the ints, floats and strings
    _conf_ints = [(key, int(value)) for key, value in parser.items('ints')]
    _conf_floats = [(key, float(value)) for key, value in parser.items('floats')]
    _conf_strings = [(key, str(value)) for key, value in parser.items('strings')]
    return dict(_conf_ints + _conf_floats + _conf_strings)

main

import os

print(os.getcwd())
#導入所有的依賴包
import  tensorflow as tf
import numpy as np
from cnnModel import cnnModel
import os
import pickle
import getConfig
import sys
#初始化一個字典,用於存儲從配置文件中讀取的參數配置
gConfig = {}
#使用get_config方法獲取配置文件中的參數
gConfig=getConfig.get_config(config_file="config.ini")

# 獲取訓練集中訓練文件的名稱
file_name = os.listdir('.../DL/CIFAR_100_homework/train_data/')[0]
print(file_name)
#創建空的多維數組用於存放圖片的二進制數據
dataset_array = np.zeros(shape=(1 * 10000, 32, 32, 3))
# 創建空的數組用於存放圖片的標註信息
dataset_labels = np.zeros(shape=(1 * 10000), dtype=np.uint8)

# 獲取測試集中訓練文件的名稱
file_name1 = os.listdir('.../DL/CIFAR_100_homework/test_data/')[0]
print(file_name1)
#創建空的多維數組用於存放圖片的二進制數據
test_array = np.zeros(shape=(1 * 10000, 32, 32, 3))
# 創建空的數組用於存放圖片的標註信息
test_labels = np.zeros(shape=(1 * 10000), dtype=np.uint8)

def unpickle_patch(file):
    #打開文件,讀取二進制文件,返回讀取到的數據
    patch_bin_file = open(file, 'rb')
    patch_dict = pickle.load(patch_bin_file, encoding='bytes')
    return patch_dict

print("正在處理數據 : ", file_name)
data_dict = unpickle_patch('.../DL/CIFAR_100_homework/train_data/' + file_name)
images_data = data_dict[b"data"]
print(images_data.shape)
# [32, 32, 3]
images_data_reshaped = np.reshape(images_data, newshape=(len(images_data), 32, 32, 3))
dataset_array = images_data_reshaped
dataset_labels = data_dict[ b'fine_labels']


print("正在處理數據 : ", file_name1)
data_dict1 = unpickle_patch('.../DL/CIFAR_100_homework/test_data/' + file_name1)
images_data1 = data_dict1[b"data"]
print(images_data1.shape)
# [32, 32, 3]
images_data_reshaped1 = np.reshape(images_data1, newshape=(len(images_data1), 32, 32, 3))
test_array = images_data_reshaped1
test_labels = data_dict1[ b'fine_labels']

#對讀取到的輸入數據進行歸一化處理
dataset_array=dataset_array.astype('float32')/255
test_array=test_array.astype('float32')/255
print(dataset_array)

#將讀取到的標註數據進行Onehot編碼
dataset_labels=tf.keras.utils.to_categorical(dataset_labels,100)
test_labels=tf.keras.utils.to_categorical(test_labels,100)
print(dataset_labels)

#定義訓練函數
def train():
    #初始化Model
    model=cnnModel(gConfig['keeps'])
    model=model.createModel()
    print(model.summary())
    model.fit(dataset_array,dataset_labels,verbose=1,epochs=gConfig['epochs'],validation_data=(test_array,test_labels))

train()

在這裏插入圖片描述

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