zoukankan      html  css  js  c++  java
  • 利用神经网络来鉴黄

    本博文适用于初学者,利用深度学习来进行图像识别的应用

    对于广大老司机们来说肯定是so easy啦

    ON.1

    首先准备大量样本,样本?从哪找,这个我相信老司机本绝对比我在行,嘻嘻

    这个我碰到过一个坑,初学者们准备样本时,正常照片和非正常照片(非正常照片?我们不是鉴黄吗?嗯嗯),本来博主准备几w张图片一起训练但是发现太麻烦了,图片中有很多脏数据,剔除脏数据就花了我很长的时间,太辣(sex)眼(feeling)了

    好啦不多说了,看代码

    这里我准备了2000张非正常图片,和2000张正常图片(本来抓取了2w张,结果训练时直接过拟合了,删到2000张时稳定了下来)

    我这里使用的是keras ,有人问我为什么不用tensorflow,keras后段可以选择tensorflow和theano,这里我使用的是tensorflow,keras的一个好处就是搭建神经网络简单快捷,相比tensorflow要节俭很多行代码,对于初学者来说很方便

    ON.2

    样本不够,没关系我们可以根据已有的图片来生成一些

    在这里我们使用keras的ImageDataGenerator,这是一个图片生成器,可以根据已有的图片来生成一些新的图片

    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我们使用了很多参数,它们都是什么意思呢

    •  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')

    净化网络环境,自觉拒绝诱惑,拥抱美丽青春,^_^

  • 相关阅读:
    安装rqalpha的日志
    从github上下载一个csv文件
    PyQt4 里的表格部件的使用方法: QTableWidget
    markdown里的多层次列表项
    打包python脚本为exe的坎坷经历, by pyinstaller方法
    Spyder docstrings文档字符串的标准
    Plot Candlestick Charts in Research of quantopian
    另类之将ipython notebook嵌入blog方法
    Jupyter Notebook Tutorial: Introduction, Setup, and Walkthrough
    爬虫视频讲座
  • 原文地址:https://www.cnblogs.com/lonenysky/p/8376843.html
Copyright © 2011-2022 走看看