一文理解tensorflow卷积神经网络

卷积与池化操作

model = keras.models.Sequential() #先生成一个模型框架
model.add(keras.layers.Conv2D(filters = 32, #卷积核个数,卷积核越多扫描出的特征越多
                              kernel_size = 3,#卷积核的大小
                              padding = 'same',#扫描后图片大小的模式
                              activation = 'selu',#激活函数
                              input_shape = (28,28,1)#输入模型的大小
                              ))
model.add(keras.layers.Conv2D(filters = 32,
                              kernel_size = 3,
                              padding = 'same',
                              activation = 'selu',
                              ))
model.add(keras.layers.MaxPool2D(pool_size = 2))#池化扫描的大小
#此处还有一个AveragePooling2D平均池化

一般的模型

google v3

在这里插入图片描述

深度可分离神经网络

在这里插入图片描述

实例代码

卷积神经网络

model = keras.models.Sequential() #先生成一个模型框架
model.add(keras.layers.Conv2D(filters = 32,
                              kernel_size = 3,
                              padding = 'same',
                              activation = 'relu',
                              input_shape = (28,28,1)
                              ))
model.add(keras.layers.BatchNormalization())                              
model.add(keras.layers.Conv2D(filters = 32,
                              kernel_size = 3,
                              padding = 'same',
                              activation = 'relu',
                              ))
model.add(keras.layers.BatchNormalization())  
model.add(keras.layers.MaxPool2D(pool_size = 2))
model.add(keras.layers.Dropout(0.3))
model.add(keras.layers.Conv2D(filters = 64,
                              kernel_size = 3,
                              padding = 'same',
                              activation = 'relu',
                              ))
model.add(keras.layers.BatchNormalization())                                
model.add(keras.layers.Conv2D(filters = 64,
                              kernel_size = 3,
                              padding = 'same',
                              activation = 'relu',
                              ))
model.add(keras.layers.BatchNormalization())                                
model.add(keras.layers.MaxPool2D(pool_size = 2))
model.add(keras.layers.Dropout(0.3))
model.add(keras.layers.Conv2D(filters = 128,
                              kernel_size = 3,
                              padding = 'same',
                              activation = 'relu',
                              ))
model.add(keras.layers.BatchNormalization())                                
model.add(keras.layers.Conv2D(filters = 128,
                              kernel_size = 3,
                              padding = 'same',
                              activation = 'relu',
                              ))
model.add(keras.layers.BatchNormalization())                                
model.add(keras.layers.MaxPool2D(pool_size = 2))
model.add(keras.layers.Dropout(0.4))
model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(256,activation = 'relu'))
model.add(keras.layers.Dropout(0.5))
model.add(keras.layers.Dense(256,activation = 'tanh'))
model.add(keras.layers.Dropout(0.5))
model.add(keras.layers.Dense(10,activation = 'softmax'))
model.summary()

深度可分离卷积神经网络

model = keras.models.Sequential() #先生成一个模型框架
model.add(keras.layers.Conv2D(filters = 32,
                              kernel_size = 3,
                              padding = 'same',
                              activation = 'selu',
                              input_shape = (28,28,1)
                              ))
model.add(keras.layers.SeparableConv2D(filters = 32,
                              kernel_size = 3,
                              padding = 'same',
                              activation = 'selu',
                              ))
model.add(keras.layers.MaxPool2D(pool_size = 2))
model.add(keras.layers.SeparableConv2D(filters = 64,
                              kernel_size = 3,
                              padding = 'same',
                              activation = 'selu',
                              ))
model.add(keras.layers.SeparableConv2D(filters = 64,
                              kernel_size = 3,
                              padding = 'same',
                              activation = 'selu',
                              ))
model.add(keras.layers.MaxPool2D(pool_size = 2))
model.add(keras.layers.SeparableConv2D(filters = 128,
                              kernel_size = 3,
                              padding = 'same',
                              activation = 'selu',
                              ))
model.add(keras.layers.SeparableConv2D(filters = 128,
                              kernel_size = 3,
                              padding = 'same',
                              activation = 'selu',
                              ))
model.add(keras.layers.MaxPool2D(pool_size = 2))
model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(128,activation = 'selu'))
model.add(keras.layers.Dense(10,activation = 'softmax'))

实战 10 Monkey数据集

包含相应库文件

import numpy as np 
import pandas as pd 
import tensorflow as tf
from tensorflow import keras
import matplotlib.pyplot as plt
import os

设置文件路径并读取标签

train_dir = "../input/10-monkey-species/training/training"#引入训练集路径
valid_dir = "../input/10-monkey-species/validation/validation"#引入验证集路径
label_file = "../input/10-monkey-species/monkey_labels.txt"#引入标签文件
print(os.path.exists(train_dir))#查看train_dir路径是否存在
print(os.path.exists(valid_dir))#查看calid_dir路径是否存在
print(os.path.exists(label_file))#查看label_file路径是否存在
print(os.listdir(train_dir))
print(os.listdir(valid_dir))
labels = pd.read_csv(label_file, header = (0))#调用pandas读取csv文件,header设置表头为第一行
print(labels)   

设置宏定义

height = 128 #设置宏变量,所有图片的高度都变成此高度
width = 128  #设置宏变量,所有图片的宽度都变成此宽度
channels = 3 #设置宏变量,所有图片的深度都变成此深度
batch_size = 128 #设置宏变量,设置每一批训练的数据多少
num_classes = 10 #设置宏变量,设置我们要划分的类别数目
epochs = 300 #设置宏变量,定义训练多少遍

读取图片并做数据增强

train_datagen = keras.preprocessing.image.ImageDataGenerator(
    rescale = 1./255.,#把所有的像素点都乘上这个数,一般用于归一化
    rotation_range = 40,#把所有图片随机旋转一个角度,旋转范围是正负这个数
    width_shift_range = 0.2,#横向位移增强所有图片在随机这个数×100%的范围进行位移
    height_shift_range = 0.2,#纵向位移增强所有图片在随机这个数×100%的范围进行位移
    shear_range = 0.2,#剪切强度
    zoom_range = 0.2,#缩放强度
    horizontal_flip = True,#是否随机的进行水平翻转
    fill_mode = 'nearest',#如果需要填充像素点那么以什么策略填充(现在是离他最近的真实像素点)
#读取图片并数据增强
train_generator = train_datagen.flow_from_directory(
    train_dir,#文件路径
    target_size = (height,width),#所有图片都缩放成这个长宽
    batch_size = batch_size,#定义没一批数据都有多少个
    seed = 7,#用来做随机的(可以随便输)
    shuffle = True,#是否打乱顺序
    class_mode = "categorical"#编码方式 one—hot之前还是之后(这里选用的是之后)  
)
#设置验证集的图片预处理方式
vaild_datagen = keras.preprocessing.image.ImageDataGenerator(rescale = 1./255.)
#对验证集进行同样的整理(唯一就是不用打乱顺序)
valid_generator = vaild_datagen.flow_from_directory(
    valid_dir,#文件路径
    target_size = (height,width),#所有图片都缩放成这个长宽
    batch_size = batch_size,#定义没一批数据都有多少个
    seed = 7,#用来做随机的(可以随便输)
    class_mode = "categorical"#编码方式 one—hot之前还是之后(这里选用的是之后)  
)
#打印数据数目
train_num = train_generator.samples
valid_num = valid_generator.samples
print(train_num, valid_num)              

取数据

for i in range(2):
    x,y = train_generator.next()
    print(x.shape,y.shape)
    print(y)

构建神经网络

model = keras.models.Sequential() #先生成一个模型框架
model.add(keras.layers.Conv2D(filters = 32,
                              kernel_size = 3,
                              padding = 'same',
                              activation = 'relu',
                              input_shape = (28,28,1)
                              ))
model.add(keras.layers.BatchNormalization())                              
model.add(keras.layers.Conv2D(filters = 32,
                              kernel_size = 3,
                              padding = 'same',
                              activation = 'relu',
                              ))
model.add(keras.layers.BatchNormalization())  
model.add(keras.layers.MaxPool2D(pool_size = 2))
model.add(keras.layers.Dropout(0.3))
model.add(keras.layers.Conv2D(filters = 64,
                              kernel_size = 3,
                              padding = 'same',
                              activation = 'relu',
                              ))
model.add(keras.layers.BatchNormalization())                                
model.add(keras.layers.Conv2D(filters = 64,
                              kernel_size = 3,
                              padding = 'same',
                              activation = 'relu',
                              ))
model.add(keras.layers.BatchNormalization())                                
model.add(keras.layers.MaxPool2D(pool_size = 2))
model.add(keras.layers.Dropout(0.3))
model.add(keras.layers.Conv2D(filters = 128,
                              kernel_size = 3,
                              padding = 'same',
                              activation = 'relu',
                              ))
model.add(keras.layers.BatchNormalization())                                
model.add(keras.layers.Conv2D(filters = 128,
                              kernel_size = 3,
                              padding = 'same',
                              activation = 'relu',
                              ))
model.add(keras.layers.BatchNormalization())                                
model.add(keras.layers.MaxPool2D(pool_size = 2))
model.add(keras.layers.Dropout(0.4))
model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(256,activation = 'relu'))
model.add(keras.layers.Dropout(0.5))
model.add(keras.layers.Dense(256,activation = 'tanh'))
model.add(keras.layers.Dropout(0.5))
model.add(keras.layers.Dense(10,activation = 'softmax'))
model.summary()

定义求解方法

model.compile(optimizer='adam',#求解模型的方法
             loss='categorical_crossentropy',#损失函数必须是向量如果已经是向量可省略sparse_
             metrics=['accuracy'])#将其他参数加入到图中,并将图固化

训练模型

history = model.fit_generator(train_generator,#前面用到的生成器
             steps_per_epoch = train_num // batch_size,#生成器会无限循环数据,所以要设置他的步数(注意不是步长)
             epochs = epochs,#训练多少轮
             validation_data = valid_generator,#验证数据的生成器
             validation_steps =valid_num // batch_size #生成器会无限循环数据,所以要设置他的步数(注意不是步长)

可视化模型训练

#可视化训练过程                             
def plot_learning_curves(history,label,epcohs,min_value,max_value):
    data={}
    data[label] = history.history[label]
    data['val_'+label] = history.history['val_'+label]
    pd.DataFrame(data).plot(figsize = (8,5))
    plt.grid(True)
    plt.axis([0,epcohs,min_value,max_value])
    plt.show()
plot_learning_curves(history,'accuracy',10,0,1)#分别模型训练时的返回值,一共训练了几轮,y轴显示下限,y轴显示上限
plot_learning_curves(history,'loss',10,1.5,2.5)#分别模型训练时的返回值,一共训练了几轮,y轴显示下限,y轴显示上限

全部代码

#包含相应库文件
import numpy as np 
import pandas as pd 
import tensorflow as tf
from tensorflow import keras
import matplotlib.pyplot as plt
import os
train_dir = "../input/10-monkey-species/training/training"#引入训练集路径
valid_dir = "../input/10-monkey-species/validation/validation"#引入验证集路径
label_file = "../input/10-monkey-species/monkey_labels.txt"#引入标签文件
print(os.path.exists(train_dir))#查看train_dir路径是否存在
print(os.path.exists(valid_dir))#查看calid_dir路径是否存在
print(os.path.exists(label_file))#查看label_file路径是否存在
print(os.listdir(train_dir))
print(os.listdir(valid_dir))
labels = pd.read_csv(label_file, header = (0))#调用pandas读取csv文件,header设置表头为第一行
print(labels)   
height = 128 #设置宏变量,所有图片的高度都变成此高度
width = 128  #设置宏变量,所有图片的宽度都变成此宽度
channels = 3 #设置宏变量,所有图片的深度都变成此深度
batch_size = 128 #设置宏变量,设置每一批训练的数据多少
num_classes = 10 #设置宏变量,设置我们要划分的类别数目
epochs = 300 #设置宏变量,定义训练多少遍

#定义keras里的ImageDataGenerator图片数据增强的参数
train_datagen = keras.preprocessing.image.ImageDataGenerator(
    rescale = 1./255.,#把所有的像素点都乘上这个数,一般用于归一化
    rotation_range = 40,#把所有图片随机旋转一个角度,旋转范围是正负这个数
    width_shift_range = 0.2,#横向位移增强所有图片在随机这个数×100%的范围进行位移
    height_shift_range = 0.2,#纵向位移增强所有图片在随机这个数×100%的范围进行位移
    shear_range = 0.2,#剪切强度
    zoom_range = 0.2,#缩放强度
    horizontal_flip = True,#是否随机的进行水平翻转
    fill_mode = 'nearest',#如果需要填充像素点那么以什么策略填充(现在是离他最近的真实像素点)
)
#读取图片并数据增强
train_generator = train_datagen.flow_from_directory(
    train_dir,#文件路径
    target_size = (height,width),#所有图片都缩放成这个长宽
    batch_size = batch_size,#定义没一批数据都有多少个
    seed = 7,#用来做随机的(可以随便输)
    shuffle = True,#是否打乱顺序
    class_mode = "categorical"#编码方式 one—hot之前还是之后(这里选用的是之后)  
)
#设置验证集的图片预处理方式
vaild_datagen = keras.preprocessing.image.ImageDataGenerator(rescale = 1./255.)
#对验证集进行同样的整理(唯一就是不用打乱顺序)
valid_generator = vaild_datagen.flow_from_directory(
    valid_dir,#文件路径
    target_size = (height,width),#所有图片都缩放成这个长宽
    batch_size = batch_size,#定义没一批数据都有多少个
    seed = 7,#用来做随机的(可以随便输)
    class_mode = "categorical"#编码方式 one—hot之前还是之后(这里选用的是之后)  
)
train_num = train_generator.samples
valid_num = valid_generator.samples
print(train_num, valid_num)              
#取数据
for i in range(2):
    x,y = train_generator.next()
    print(x.shape,y.shape)
    print(y)
#定义模型
model = keras.models.Sequential() #先生成一个模型框架
model.add(keras.layers.Conv2D(filters = 32,
                              kernel_size = 3,
                              padding = 'same',
                              activation = 'relu',
                              input_shape = (28,28,1)
                              ))
model.add(keras.layers.BatchNormalization())                              
model.add(keras.layers.Conv2D(filters = 32,
                              kernel_size = 3,
                              padding = 'same',
                              activation = 'relu',
                              ))
model.add(keras.layers.BatchNormalization())  
model.add(keras.layers.MaxPool2D(pool_size = 2))
model.add(keras.layers.Dropout(0.3))
model.add(keras.layers.Conv2D(filters = 64,
                              kernel_size = 3,
                              padding = 'same',
                              activation = 'relu',
                              ))
model.add(keras.layers.BatchNormalization())                                
model.add(keras.layers.Conv2D(filters = 64,
                              kernel_size = 3,
                              padding = 'same',
                              activation = 'relu',
                              ))
model.add(keras.layers.BatchNormalization())                                
model.add(keras.layers.MaxPool2D(pool_size = 2))
model.add(keras.layers.Dropout(0.3))
model.add(keras.layers.Conv2D(filters = 128,
                              kernel_size = 3,
                              padding = 'same',
                              activation = 'relu',
                              ))
model.add(keras.layers.BatchNormalization())                                
model.add(keras.layers.Conv2D(filters = 128,
                              kernel_size = 3,
                              padding = 'same',
                              activation = 'relu',
                              ))
model.add(keras.layers.BatchNormalization())                                
model.add(keras.layers.MaxPool2D(pool_size = 2))
model.add(keras.layers.Dropout(0.4))
model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(256,activation = 'relu'))
model.add(keras.layers.Dropout(0.5))
model.add(keras.layers.Dense(256,activation = 'tanh'))
model.add(keras.layers.Dropout(0.5))
model.add(keras.layers.Dense(10,activation = 'softmax'))
model.summary() 
model.compile(optimizer='adam',#求解模型的方法
             loss='categorical_crossentropy',#损失函数必须是向量如果已经是向量可省略sparse_
             metrics=['accuracy'])#将其他参数加入到图中,并将图固化
history = model.fit_generator(train_generator,#前面用到的生成器
             steps_per_epoch = train_num // batch_size,#生成器会无限循环数据,所以要设置他的步数(注意不是步长)
             epochs = epochs,#训练多少轮
             validation_data = valid_generator,#验证数据的生成器
             validation_steps =valid_num // batch_size #生成器会无限循环数据,所以要设置他的步数(注意不是步长)
#可视化训练过程                             
def plot_learning_curves(history,label,epcohs,min_value,max_value):
    data={}
    data[label] = history.history[label]
    data['val_'+label] = history.history['val_'+label]
    pd.DataFrame(data).plot(figsize = (8,5))
    plt.grid(True)
    plt.axis([0,epcohs,min_value,max_value])
    plt.show()
plot_learning_curves(history,'acc',10,0,1)#分别模型训练时的返回值,一共训练了几轮,y轴显示下限,y轴显示上限
plot_learning_curves(history,'loss',10,1.5,2.5)#分别模型训练时的返回值,一共训练了几轮,y轴显示下限,y轴显示上限
                   )

迁移学习

模型获取

from keras.applications.xception import Xception
from keras.applications.vgg16 import VGG16
from keras.applications.vgg19 import VGG19
from keras.applications.resnet import ResNet50
from keras.applications.resnet import ResNet101
from keras.applications.resnet import ResNet152
from keras.applications.resnet_v2 import ResNet50V2
from keras.applications.resnet_v2 import ResNet101V2
from keras.applications.resnet_v2 import ResNet152V2
from keras.applications.resnext import ResNeXt50
from keras.applications.resnext import ResNeXt101
from keras.applications.inception_v3 import InceptionV3
from keras.applications.inception_resnet_v2 import InceptionResNetV2
from keras.applications.mobilenet import MobileNet
from keras.applications.mobilenet_v2 import MobileNetV2
from keras.applications.densenet import DenseNet121
from keras.applications.densenet import DenseNet169
from keras.applications.densenet import DenseNet201
from keras.applications.nasnet import NASNetLarge
from keras.applications.nasnet import NASNetMobile

model = VGG16(weights='imagenet', include_top=True)

调整输入大小

每个模型都有自己的输入大小所以要去官网查一下
在这里使用的ResNet是 224×224的

设置同样的数据输入处理

#定义keras里的ImageDataGenerator图片数据增强的参数
train_datagen = keras.preprocessing.image.ImageDataGenerator(
    preprocessing_function = keras.applications.resnet50.preprocess_input,#在这里按照不同的方法对模型进行输入处理
    rotation_range = 40,#把所有图片随机旋转一个角度,旋转范围是正负这个数
    width_shift_range = 0.2,#横向位移增强所有图片在随机这个数×100%的范围进行位移
    height_shift_range = 0.2,#纵向位移增强所有图片在随机这个数×100%的范围进行位移
    shear_range = 0.2,#剪切强度
    zoom_range = 0.2,#缩放强度
    horizontal_flip = True,#是否随机的进行水平翻转
    fill_mode = 'nearest',#如果需要填充像素点那么以什么策略填充(现在是离他最近的真实像素点)点
)

获取模型和自己的层次进行拼接

model = keras.models.Sequential() #先生成一个模型框架
model.add(keras.applications.ResNet50(
    include_top = False, #是否去掉最后的那些全连接层
    pooling = 'avg',#因为去掉后是卷积层所以要把数据展平
    weights = 'imagenet',#设置权重是什么数据集的
))
model.add(keras.layers.Dense(num_classes, activation = 'softmax'))#添加我们加入的全连接层
model.layers[0].trainable = False #冻结住层一,让他的参数不再变化
model.summary()


#或者微调模型
resnet50 = keras.applications.ResNet50(
    include_top = False,#是否去掉最后的那些全连接层
    pooling = 'avg',#因为去掉后是卷积层所以要把数据展平
    weights = 'imagenet',#设置权重是什么数据集的
for layer in resnet50.layers[0:-5]:#在这里遍历层次(从第几层,到第几层)
    layer.trainable = False#关闭该层的可训练开关
model = keras.models.Sequential([
    resnet50,
    keras.layers.Dense(num_classes, activation = 'softmax'),
])
)

定义模型求解方式和训练模型

model.compile(optimizer='sgd',#sgd求解模型时间长,但可以达到极小值
             loss='categorical_crossentropy',#损失函数必须是向量如果已经是向量可省略sparse_
             metrics=['accuracy'])#将其他参数加入到图中,并将图固化
epochs = 10#定义模型中的训练轮数
history = model.fit_generator(train_generator,
                             steps_per_epoch = train_num // batch_size,
                             epochs = epochs,
                             validation_data = valid_generator,
                             validation_steps =valid_num // batch_size 
                   )

可视化模型

def plot_learning_curves(history,label,epochs,min_value,max_value):
    data={}
    data[label] = history.history[label]
    data['val_'+label] = history.history['val_'+label]
    pd.DataFrame(data).plot(figsize = (8,5))
    plt.grid(True)
    plt.axis([0,epochs,min_value,max_value])
    plt.show()
plot_learning_curves(history,'accuracy',epochs,0,1)
plot_learning_curves(history,'loss',epochs,0,2.5)

ResNet50迁移学习实战cifar-10 95%

包含库文件

import numpy as np
import pandas as pd 
import tensorflow as tf
from tensorflow import keras
import matplotlib.pyplot as plt
from sklearn import preprocessing
import cv2
import os

获取数据

(x_train, y_train), (x_test, y_test) = keras.datasets.cifar10.load_data()#从keras指定的地方下载cifar-10数据集并划分训练集测试集

数据处理

创建保存data的文件夹

train_dir = '/kaggle/working/train'#设置训练数据存放在哪里
test_dir = '/kaggle/working/test'#设置测试数据存放在哪里
if  not (os.path.exists(train_dir)):#如果没有训练数据存放的文件夹
    os.makedirs(train_dir)         #就创建这个文件夹
if  not (os.path.exists(test_dir)):#如果没有测试数据存放的文件夹
    os.makedirs(test_dir)          #就创建这个文件夹

写入数据 并按照(文件路径/标签)的形式返回数据存放信息

def save_data(x_train, y_train, path):
    data_amount = len(x_train)
    assert(data_amount == len(y_train)), '数据与标签不匹配'
    assert(y_train.shape[1] == 1), '标签必须是一列数据'
    assert(os.path.exists(path)), '填写的目录不存在'
    _list = []
    for i in range(data_amount):
        cv2.imwrite( "{}/data_{}.png".format(path,i), x_train[i])
        _list.append(["{}/data_{}.png".format(path,i),'{}'.format(y_train[i][0])])
    data_pd = pd.DataFrame(_list)
    data_pd.columns = ['filepath','class']
    del _list
    return data_pd
train_pd = save_data(x_train, y_train, train_dir)#填写数据集,标签,和存放目录
test_pd = save_data(x_test, y_test, test_dir)#填写数据集,标签,和存放目录

设置宏变量

height = 224 #设置宏变量,所有图片的高度都变成此高度
width = 224  #设置宏变量,所有图片的宽度都变成此宽度
channels = 3 #设置宏变量,所有图片的深度都变成此深度
batch_size = 20 #设置宏变量,设置每一批训练的数据多少
num_classes = 10 #设置宏变量,设置我们要划分的类别数目
epochs = 10 #设置宏变量,定义训练多少遍

数据增强

train_datagen = keras.preprocessing.image.ImageDataGenerator(
    preprocessing_function = keras.applications.resnet50.preprocess_input,#resnet50独有的数据处理方法
    rotation_range = 40,#设置随机旋转多少角度
    width_shift_range = 0.2,#设置随机横向位移百分比
    height_shift_range = 0.2,#设置随机纵向位移百分比
    shear_range = 0.2,#设置剪切强度
    zoom_range = 0.2,#设置缩放强度
    horizontal_flip = True,#是否随机的进行水平翻转
    fill_mode = 'nearest',#编码方式 one—hot之前还是之后(这里选用的是之前) 
)
test_datagen = keras.preprocessing.image.ImageDataGenerator(
    preprocessing_function = keras.applications.resnet50.preprocess_input,#resnet50独有的数据处理方法
)
train_generator = train_datagen.flow_from_dataframe(
    train_pd, #包含需要处理的数据文件目录和标签的panadas
    directory = '/kaggle',#设置根目录
    x_col = 'filepath',#数据列名
    y_col = 'class',#标签列名
    target_size = (height,width),#图片将缩放成这个大小
    batch_size = batch_size,#没一批处理多少数据
    seed = 7,#随机数种子
    shuffle = True,#是否打乱顺序
    class_mode = 'categorical',#编码方式 one—hot之前还是之后(这里选用的是之后)  
)
#测试集不需要打乱顺序
test_generator = test_datagen.flow_from_dataframe(
    test_pd,#包含需要处理的数据文件目录和标签的panadas
    directory = '/kaggle',#设置根目录
    x_col = 'filepath',#数据列名
    y_col = 'class',#标签列名
    target_size = (height,width),#图片将缩放成这个大小
    batch_size = batch_size,#没一批处理多少数据
    seed = 7,#随机数种子
    class_mode = 'categorical',#编码方式 one—hot之前还是之后(这里选用的是之后) 
)

定义模型

keras.backend.set_learning_phase(0)
Inp = keras.layers.Input((224, 224, 3))
base_model = keras.applications.ResNet50(weights='imagenet', include_top=False,
                              input_shape=(height, width, 3), )
keras.backend.set_learning_phase(1)
x = base_model(Inp)
x = keras.layers.BatchNormalization()(x, training=False)
x = keras.layers.GlobalAveragePooling2D(name='average_pool')(x)
x = keras.layers.Flatten(name='flatten')(x)
x = keras.layers.Dense(2048, activation='relu')(x)
x = keras.layers.Dense(1024, activation='tanh')(x)
predictions = keras.layers.Dense(num_classes, activation='softmax')(x)
model = keras.Model(inputs=Inp, outputs=predictions)

定义模型优化方法

model.compile(optimizer='sgd',#sgd求解模型时间长,但可以达到极小值
             loss='categorical_crossentropy',#损失函数必须是向量如果已经是向量可省略sparse_
             metrics=['accuracy'])#将其他参数加入到图中,并将图固化

训练数据

history = model.fit_generator(train_generator,#前面用到的生成器
                             steps_per_epoch = len(train_pd) // batch_size,#生成器会无限循环数据,所以要设置他的步数(注意不是步长)
                             epochs = epochs,#训练多少轮
                             validation_data = test_generator,#验证数据的生成器
                             validation_steps = len(test_pd) // batch_size #生成器会无限循环数据,所以要设置他的步数(注意不是步长)

可视化训练结果

def plot_learning_curves(history,label,epochs,min_value,max_value):
    data={}
    data[label] = history.history[label]
    data['val_'+label] = history.history['val_'+label]
    pd.DataFrame(data).plot(figsize = (8,5))
    plt.grid(True)
    plt.axis([0,epochs,min_value,max_value])
    plt.show()
plot_learning_curves(history,'accuracy',epochs,0,1)
plot_learning_curves(history,'loss',epochs,0,2.5)  

全部代码

#包含所需要的库文件
import numpy as np
import pandas as pd 
import tensorflow as tf
from tensorflow import keras
import matplotlib.pyplot as plt
from sklearn import preprocessing
import cv2
import os
#获取数据
(x_train, y_train), (x_test, y_test) = keras.datasets.cifar10.load_data()
#配置文件路径,创建train和test两个文件夹
train_dir = '/kaggle/working/train'
test_dir = '/kaggle/working/test'
if  not (os.path.exists(train_dir)):
    os.makedirs(train_dir)
if  not (os.path.exists(test_dir)):
    os.makedirs(test_dir)
#将数据写入文件夹,并按照(文件目录,标签)的模式写好pandas
def save_data(x_train, y_train, path):
    data_amount = len(x_train)
    assert(data_amount == len(y_train)), '数据与标签不匹配'
    assert(y_train.shape[1] == 1), '标签必须是一列数据'
    assert(os.path.exists(path)), '填写的目录不存在'
    _list = []
    for i in range(data_amount):
        cv2.imwrite( "{}/data_{}.png".format(path,i), x_train[i])
        _list.append(["{}/data_{}.png".format(path,i),'{}'.format(y_train[i][0])])
    data_pd = pd.DataFrame(_list)
    data_pd.columns = ['filepath','class']
    del _list
    return data_pd
train_pd = save_data(x_train, y_train, train_dir)
test_pd = save_data(x_test, y_test, test_dir)
#设置宏变量
height = 224 #设置宏变量,所有图片的高度都变成此高度
width = 224  #设置宏变量,所有图片的宽度都变成此宽度
channels = 3 #设置宏变量,所有图片的深度都变成此深度
batch_size = 20 #设置宏变量,设置每一批训练的数据多少
num_classes = 10 #设置宏变量,设置我们要划分的类别数目
epochs = 10 #设置宏变量,定义训练多少遍
#定义keras里的ImageDataGenerator图片数据增强的参数
train_datagen = keras.preprocessing.image.ImageDataGenerator(
    preprocessing_function = keras.applications.resnet50.preprocess_input,
    rotation_range = 40,
    width_shift_range = 0.2,
    height_shift_range = 0.2,
    shear_range = 0.2,
    zoom_range = 0.2,
    horizontal_flip = True,
    fill_mode = 'nearest',
)
test_datagen = keras.preprocessing.image.ImageDataGenerator(
    preprocessing_function = keras.applications.resnet50.preprocess_input,
)
train_generator = train_datagen.flow_from_dataframe(
    train_pd,
    directory = '/kaggle',
    x_col = 'filepath',
    y_col = 'class',
    target_size = (height,width),
    batch_size = batch_size,
    seed = 7,
    shuffle = True,
    class_mode = 'categorical',
)
test_generator = test_datagen.flow_from_dataframe(
    test_pd,
    directory = '/kaggle',
    x_col = 'filepath',
    y_col = 'class',
    target_size = (height,width),
    batch_size = batch_size,
    seed = 7,
    class_mode = 'categorical',
)
#设置模型
keras.backend.set_learning_phase(0)
Inp = keras.layers.Input((224, 224, 3))
base_model = keras.applications.ResNet50(weights='imagenet', include_top=False,
                              input_shape=(height, width, 3), )
keras.backend.set_learning_phase(1)
x = base_model(Inp)
x = keras.layers.BatchNormalization()(x, training=False)
x = keras.layers.GlobalAveragePooling2D(name='average_pool')(x)
x = keras.layers.Flatten(name='flatten')(x)
x = keras.layers.Dense(2048, activation='relu')(x)
x = keras.layers.Dense(1024, activation='tanh')(x)
predictions = keras.layers.Dense(num_classes, activation='softmax')(x)
model = keras.Model(inputs=Inp, outputs=predictions)
#设置求解模型的方法
model.compile(optimizer='sgd',
             loss='categorical_crossentropy',
             metrics=['accuracy'])
#训练数据             
history = model.fit_generator(train_generator,
                             steps_per_epoch = len(train_pd) // batch_size,
                             epochs = epochs,
                             validation_data = test_generator,
                             validation_steps = len(test_pd) // batch_size 
                   )
#可视化数据                   
def plot_learning_curves(history,label,epochs,min_value,max_value):
    data={}
    data[label] = history.history[label]
    data['val_'+label] = history.history['val_'+label]
    pd.DataFrame(data).plot(figsize = (8,5))
    plt.grid(True)
    plt.axis([0,epochs,min_value,max_value])
    plt.show()
plot_learning_curves(history,'accuracy',epochs,0,1)
plot_learning_curves(history,'loss',epochs,0,2.5)                   

cnn总结

输入感受野维度:图像的默认值为 2D,但可以是 1D,例如句子中的单词或添加时间维度的视频的 3D。
感受野的大小:patch应尽可能小,但应该大到足以“看到”输入数据中的特征,通常在小图像上使用 3×3,在较大图像尺寸上使用 5×57×7 或更多。
步幅宽度:使用默认步幅 1.这很容易理解,并且您不需要填充来处理从图像边缘掉落的感受野。对于较大的图像,这可以增加到 2 或更大。
滤波器数量:滤波器是特征检测器,通常在输入层使用较少的滤波器,并且在较深层使用的滤波器越来越多。
填充:设置为零并在读取非输入数据时调用零填充。当您不能或不想标准化输入图像大小或想要使用不能整齐划分输入图像大小的感知字段和步幅大小时,这将非常有用。
池化:池化是一种破坏性或泛化过程,以减少过拟合,感受野几乎总是设置为 2×2,步幅为 2,以丢弃前一层输出的 75%激活。
数据准备:考虑标准化输入数据,包括图像尺寸和像素值。
模式体系结构:通常在网络体系结构中对层进行模式化。这可能是一个,两个或一些卷积层,后面是池化层。然后可以重复该结构一次或多次。最后,完全连接层通常仅在输出端使用,并且可以堆叠一个,两个或更多个深度。
dropout:CNN 容易造成一种过拟合,即使是池化层也是如此,应该在完全连接的层之间,或池化层之后使用Dropout。
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值