利用神經網絡來鑑黃

本博文適用於初學者,利用深度學習來進行圖像識別的應用數組

對於廣大老司機們來講確定是so easy啦網絡

ON.1

首先準備大量樣本,樣本?從哪找,這個我相信老司機本絕對比我在行,嘻嘻app

這個我碰到過一個坑,初學者們準備樣本時,正常照片和非正常照片(非正常照片?咱們不是鑑黃嗎?嗯嗯),原本博主準備幾w張圖片一塊兒訓練可是發現太麻煩了,圖片中有不少髒數據,剔除髒數據就花了我很長的時間,太辣(sex)眼(feeling)了函數

好啦很少說了,看代碼學習

這裏我準備了2000張非正常圖片,和2000張正常圖片(原本抓取了2w張,結果訓練時直接過擬合了,刪到2000張時穩定了下來)優化

我這裏使用的是keras ,有人問我爲何不用tensorflow,keras後段能夠選擇tensorflow和theano,這裏我使用的是tensorflow,keras的一個好處就是搭建神經網絡簡單快捷,相比tensorflow要節儉不少行代碼,對於初學者來講很方便編碼

ON.2

樣本不夠,不要緊咱們能夠根據已有的圖片來生成一些spa

在這裏咱們使用keras的ImageDataGenerator,這是一個圖片生成器,能夠根據已有的圖片來生成一些新的圖片code

datagen = ImageDataGenerator(rescale=1./255,horizontal_flip=True,vertical_flip=True,shear_range=.2,width_shift_range=.2,height_shift_range=.2,data_format='channels_last')

ImageDataGenerator咱們使用了不少參數,它們都是什麼意思呢orm

  •  data_format:分爲channel_first和channel_last,這裏咱們可不要選錯了,channel_first是theano所使用的格式,channel_last是tensorflow所使用的格式,以128x128的RGB圖像爲例,「channel_first」應將數據組織爲(3,128,128),而「channel_last」應將數據組織爲(128,128,3)
  •  rescale:重放縮因子,默認爲None,若是爲None或0則不進行放縮
  •  horizontal_flip:布爾值,進行隨機水平翻
  •    vertical_flip:布爾值,進行隨機豎直翻轉
  •    shear_range:浮點數,剪切強度(逆時針方向的剪切變換角度)
  •    width_shift_range:浮點數,圖片寬度的某個比例,數據提高時圖片水平偏移的幅度
  •    height_shift_range:浮點數,圖片高度的某個比例,數據提高時圖片豎直偏移的幅度

這裏咱們使用的圖片大小是(150,150)

img_width, img_height = 150, 150

train_data_dir = 'py/Scrapy/classifier/img/abnormal'
validation_data_dir = 'py/Scrapy/classifier/img/test'

datagen = ImageDataGenerator(rescale=1./255,horizontal_flip=True,vertical_flip=True,shear_range=.2,width_shift_range=.2,height_shift_range=.2,data_format='channels_last')

train_generator = datagen.flow_from_directory(
        train_data_dir,
        target_size=(img_width, img_height),
        batch_size=32,
        class_mode='binary')

validation_generator = datagen.flow_from_directory(
        validation_data_dir,
        target_size=(img_width, img_height),
        batch_size=32,
        class_mode='binary')

batch_size是batch數據的大小,這裏咱們是32,即一次傳入多上張圖片

class_mode:"categorical", "binary", "sparse"或None之一. 默認爲"categorical. 該參數決定了返回的標籤數組的形式, "categorical"會返回2D的one-hot編碼標籤,"binary"返回1D的二值標籤."sparse"返回1D的整數標籤,若是爲None則不返回任何標籤, 生成器將僅僅生成batch數據

由於咱們是一個二分類的問題,因此咱們選擇binary

如今咱們的樣本問題解決了,開始搭建咱們的神經網絡模型吧

 

有些人擔憂本身的設備內存會爆掉,不用擔憂ImageDataGenerator實際上是Python的迭代器,把咱們的batch_size調小一點一次傳入少許的圖片就能夠啦

 

NO.3

簡單來講咱們把數據格式爲(150,150,3)的數據傳入到神經網絡中,(150,150,3)這個是什麼意思,這個是(img_width,img_height,圖片通道),彩色圖片通道是3,灰色圖片的爲1

model=Sequential()
model.add(Conv2D(32,3,3,input_shape=(img_width,img_height,3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Conv2D(32,3,3))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Conv2D(64,3,3))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Flatten())
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(1))
model.add(Activation('sigmoid'))

Activation('relu')即激活層,這裏咱們添加一個relu的激活函數

MaxPooling2D是池化層,池化層每每跟在卷積層後面,池化層把以前卷基層獲得的特徵圖作一個聚合統計,100*100的大小選擇一個2*2的區域作不重疊的最大池化,池化層回輸出50*50的那麼大的圖來達到下降數據量的目的,這裏咱們是150*150,通過最大池化後池化層輸出75*75

通過三層卷積層,池化操做後通過Flateen()

Flateen():把多位的輸入變成一維的,一般在卷積層到全lian jie ceng全鏈接層的過分,Flatten不影響batch的大小

Dense:全鏈接層

Dropout:在訓練過程當中每次更新參數時按必定機率(rate)隨機斷開輸入神經元,Dropout層用於防止過擬合

直接咱們的輸出層大小爲1,即咱們只輸出一個數據Dense(1),輸出層的激活函數爲sigmoid,sigmoid通常用於二分類問題

 

NO.4

這裏咱們建立一個Callback用於記錄咱們的loss值

from keras.callbacks import Callback
class LossHistory(Callback):
    def on_train_begin(self, logs={}):
        self.losses = []

    def on_batch_end(self, batch, logs={}):
        self.losses.append(logs.get('loss'))

下面進入正題開始訓練

history_loss=LossHistory()
model.compile(loss='binary_crossentropy',optimizer='rmsprop',metrics=['accuracy'])
nb_epoch=10
nb_train_smaple=4668
nb_validation_samples=392
model.fit_generator(train_generator,samples_per_epoch=nb_train_smaple,nb_epoch=nb_epoch,validation_data=validation_generator,nb_val_samples=nb_validation_samples,callbacks=[history_loss])

由於咱們是個二分類問題因此損失函數咱們選擇binary_crossentropy

激活函數這裏咱們再也不講解你們能夠自行百度,這裏使用rmsprop或者adam,使用adam則相對好一些

nb_epoch是訓練的次數這裏作個演示咱們僅僅訓練10輪

validation_data要填寫咱們咱們驗證的生成器函數

samples_per_epoch即每個epoch樣本數達到多少時記一個epoch結束

通過訓練後

 

達到了92%的識別率,這裏你們能夠在進行一些優化或者增長訓練的次數

 博主你出來第三個是什麼~

 

NO.4

放出全部的代碼

from keras.preprocessing.image import ImageDataGenerator,array_to_img,img_to_array,load_img
from keras.models import Sequential
from keras.layers import Dense,Flatten,Conv2D,MaxPooling2D,Dropout,Activation


img_width, img_height = 150, 150

train_data_dir = 'py/Scrapy/classifier/img/abnormal'
validation_data_dir = 'py/Scrapy/classifier/img/test'

datagen = ImageDataGenerator(rescale=1./255)




train_generator = datagen.flow_from_directory(
        train_data_dir,
        target_size=(img_width, img_height),
        batch_size=32,
        class_mode='binary')

validation_generator = datagen.flow_from_directory(
        validation_data_dir,
        target_size=(img_width, img_height),
        batch_size=32,
        class_mode='binary')

model=Sequential()
model.add(Conv2D(32,3,3,input_shape=(img_width,img_height,3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Conv2D(32,3,3))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Conv2D(64,3,3))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Flatten())
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(1))
model.add(Activation('sigmoid'))
model.compile(loss='binary_crossentropy',optimizer='adam',metrics=['accuracy'])
nb_epoch=10
nb_train_smaple=4668
nb_validation_samples=392
model.fit_generator(train_generator,samples_per_epoch=nb_train_smaple,nb_epoch=nb_epoch,validation_data=validation_generator,nb_val_samples=nb_validation_samples)
model.save_weights('./abnormal.h5')

from keras.utils import plot_model
plot_model(model,to_file='./model.png')

 

淨化網絡環境,自覺拒絕誘惑,擁抱美麗青春,^_^

相關文章
相關標籤/搜索