1、keras数据集的制作 2、keras如何加载自己制作的数据集

前言

在接触keras之后,一开始的实验都是用keras内置的数据集,比如mnist数据集,直接用一行代码直接导入就好了。但是在学习的深入,想要导入自己所需要的数据集,下面就分两个大部分介绍

第一部分:keras数据集的制作

这一部分是参考这篇博客的:https://blog.csdn.net/baidu_35113561/article/details/79413308

以下类容作为自己的笔记记录下来

第一步:寻找和建立样本

captcha本身提供了用户自定义验证码生成API,利用它,我们可以轻松的建立样本。样本数目不要太少,视项目具体情况而定(本项目一般50000个左右)。网上有很多资源关于如何用captcha生成*.png的验证码,这里就不再赘述。

第二部:为样本打好标签(label)

得到了样本后我们下面一步要做的就是给样本打标签。作为一个监督学习的项目,我们有义务告诉计算机什么样的结果是正确的,什么样的结果是错误的。如果说X_train为样本的话,我们这里要做的便是得到y_train。打标签的方法有很多,比如建立*.txt文件对应样本一一做标签。Concretely, 本项目中,captcha在随机生成验证码 的同时已经将相应验证码样本命名为了代表其含义的png文件前缀(下图所示),这非常利于我们做标签。

1、keras数据集的制作 2、keras如何加载自己制作的数据集_第1张图片

训练这个项目的最简单方法就是建立n个神经网络并训练机器使其能够分辨第n位字符(n为验证码长度)。例如要训练机器识别第一位字符,我们要做的便是检索每个样本文件名,将其对应的ASCII码提取出来,经过处理①并写入*.txt中,这样就得到标签了。关于如何提取字符ascii,可自行网上搜索,相关资源很丰富。

①处理:将26个字母编码,比如:0代表A,1代表B,2代表C...........这样keras之后就能通过one_hot编码了。

第三部:导入数据集

这里,我们通过numpy和PIL两个库。

先说导入图片,这里我们的图片格式是RGB 60*160 png。单张图片灰度化和导入使用PIL(opencv也可以)。因为我们需要导入整个样本库,所以需要用append函数把新的单张图片矩阵加到整个矩阵集合里,这之前当然要定义一个数组来作为集合,如images = []。之后再使用X = numpy.array(images),这样便得到了numpy格式的数据集。导入完毕后,我们可以通过print(X.shape)看看导入是否正确,例如我们导入了30000张60*160的图片,应得到:(30000, 60, 160)

然后是导入标签,即y。直接y = numpy.loadtxt('*.txt')即可。之后print (y.shape)应得到:(30000,),注意样本数和标签数一定要对应。

第四步:得到训练集和测试集(X_train,X_test,y_train,y_test)

此项目,我们可以使用sklearn库中的train_test_split函数将整个数据集分成训练集和测试集(X_train,X_test,y_train,y_test),此函数还有一个优点是会打乱顺序,比较好。关于该函数用法可自行百度。提供个参考:X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.3, random_state= 30)


通过上述四步,我们便人工完成了如下函数功能:(X_train, y_train), (X_test, y_test) = mnist.load_data()

之后reshape下X_train,X_test,y_train,y_test,搭建网络,训练即可。
 

源码:https://github.com/YingjieZhang31/Captcha-Verification-Code-Recognition

import os
import numpy as np
np.random.seed(1337)
from keras.datasets import mnist
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers import Dropout, Dense, Activation, Convolution2D, MaxPooling2D, ZeroPadding2D, Flatten
from keras.optimizers import Adam
from sklearn.model_selection import train_test_split
from PIL import Image
###########################################################################
def read_image(img_name):
    im = Image.open(img_name).convert('L')
    data = np.array(im)
    return data

images = []
for fn in os.listdir('./images'):
    if fn.endswith('.png'):
        fd = os.path.join('./images',fn)
        images.append(read_image(fd))
print('load success!')
X = np.array(images)
print (X.shape)

y = np.loadtxt('out.txt')
print (y.shape)

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state= 30)
print (X_train.shape)
print (X_test.shape)
print (y_train.shape)
print (y_test.shape)

print("Changing format......")

X_train = X_train.reshape(-1, 1,60, 160)/255.
X_test = X_test.reshape(-1, 1,60, 160)/255.
y_train = np_utils.to_categorical(y_train, num_classes=26)
y_test = np_utils.to_categorical(y_test, num_classes=26)

print (X_train.shape)
print (X_test.shape)
print (y_train.shape)
print (y_test.shape)

print("Changing succeeded!")
os.system("pause")
#########################################################################
model = Sequential()
##1:64
model.add(Convolution2D(
		nb_filter = 64,
		nb_row = 3,
		nb_col = 3,
		border_mode = 'same',
		input_shape=(1,60,160)
						)
		)
model.add(Activation('relu'))
model.add(Dropout(0.2))

model.add(MaxPooling2D(
					pool_size = (2,2),
					strides = (2,2),
					border_mode = 'same',
					)
		)

##2:128
model.add(Convolution2D(128, 3, 3, border_mode = 'same'))
model.add(Activation('relu'))
model.add(Dropout(0.2)) 
model.add(MaxPooling2D(2, 2, border_mode = 'same'))

##3:256
model.add(Convolution2D(256, 3, 3, border_mode = 'same'))
model.add(Activation('relu'))
model.add(Dropout(0.2)) 
model.add(MaxPooling2D(2, 2, border_mode = 'same'))

##4:512
model.add(Convolution2D(512, 3, 3, border_mode = 'same'))
model.add(Activation('relu'))
model.add(Dropout(0.2)) 
model.add(MaxPooling2D(2, 2, border_mode = 'same'))

##5:512
model.add(Convolution2D(512, 3, 3, border_mode = 'same'))
model.add(Activation('relu'))
model.add(Dropout(0.2)) 
model.add(MaxPooling2D(2, 2, border_mode = 'same'))

#####FC
model.add(Flatten())
model.add(Dense(2048, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(2048, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(26, activation='softmax'))
########################
adam = Adam(lr = 1e-4)

########################
model.compile(optimizer=adam,
              loss='categorical_crossentropy',
              metrics=['accuracy'])

print('Training ------------')
# Another way to train the model
model.fit(X_train, y_train, epochs=30, batch_size=64,)

print('\nTesting ------------')
# Evaluate the model with the metrics we defined earlier
loss, accuracy = model.evaluate(X_test, y_test)

print('\ntest loss: ', loss)
print('\ntest accuracy: ', accuracy)

model.save('cnn_model.h5')   # HDF5文件,pip install h5py
print('\nSuccessfully saved as cnn_model.h5')



第二部分:keras如何加载自己制作的数据集

直接在代码当中来看吧,下面这个代码是DCGAN生成卡通人物图像

import numpy as np
from sklearn.model_selection import train_test_split
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Activation, Flatten, Reshape
from keras.layers import Conv2D, Conv2DTranspose, UpSampling2D
from keras.layers import LeakyReLU, Dropout
from keras.layers import BatchNormalization
from keras.optimizers import RMSprop
import matplotlib.pyplot as plt
from PIL import Image
import cv2
import os
from keras.preprocessing.image import ImageDataGenerator
from keras.layers import BatchNormalization,Activation,ZeroPadding2D
from keras.optimizers import Adam,RMSprop
from keras.preprocessing import image
from keras.models import load_model
class DCGAN(object):
    def __init__(self, img_rows=96, img_cols=96, channel=3):
        #初始化图片的行列通道数
        self.img_rows = img_rows
        self.img_cols = img_cols
        self.channel = channel
        self.D = None  # discriminator判别器
        self.G = None  # generator生成器
        self.AM = None # adversarial model 对抗模型
        self.DM = None # discriminator model 判别模型
        
    
#     def get_imgs():
#         files = os.listdir("F:/Data/faces1.7z/faces/")
#         imgs = []
#         for file in files:
#             imgs.append(cv2.imread("F:/Data/faces1.7z/faces/" + file))
#         print("get_imgs")
#         return imgs

        
    # 判别模型
    def discriminator(self):
        if self.D:
            return self.D
        self.D = Sequential()
        # 定义通道数
        depth = 64
        #dropout系数
        dropout = 0.4
        
        #输入96*96*3
        input_shape = (self.img_rows, self.img_cols, self.channel)
        
        #输出49*49*64
        '''
        Conv2D(filters:输出的维数, kernel_size卷积窗口的大小, strides:卷积的步幅, padding:填充的方式)
        LeakyReLU()激活函数,ReLU的变形激活函数
        14怎么来的(28 - 5 + 2*2【padding需要补两个2,根据公式需要乘二】  /  2【strides】) = 14
        '''
        self.D.add(Conv2D(depth*1, 5, strides=2, input_shape=input_shape, padding='same'))
        self.D.add(LeakyReLU(alpha=0.2)) 
        self.D.add(Dropout(dropout))
#         self.D.add(LeakyReLU(alpha=0.2))
#         self.D.add(Dropout(0.25))
        
        #输出23*23*128
        self.D.add(Conv2D(depth*2, 5, strides=2, padding='same'))
        self.D.add(LeakyReLU(alpha=0.2)) 
        self.D.add(Dropout(dropout))
#         self.D.add(ZeroPadding2D(padding=((0, 1), (0, 1))))
#         self.D.add(BatchNormalization(momentum=0.8))
#         self.D.add(LeakyReLU(alpha=0.2))
#         self.D.add(Dropout(0.25))

        # 输出11*11*256
        self.D.add(Conv2D(depth*4, 5, strides=2, padding='same'))
        self.D.add(LeakyReLU(alpha=0.2)) 
        self.D.add(Dropout(dropout))
#         self.D.add(BatchNormalization(momentum=0.8))
#         self.D.add(LeakyReLU(alpha=0.2))
#         self.D.add(Dropout(0.25))
        
        # 输出11*11*512
        self.D.add(Conv2D(depth*8, 5, strides=1, padding='same'))
        self.D.add(LeakyReLU(alpha=0.2)) 
        self.D.add(Dropout(dropout))
#         self.D.add(BatchNormalization(momentum=0.8))
#         self.D.add(LeakyReLU(alpha=0.2))
#         self.D.add(Dropout(0.25))
        
        # 全连接层
        self.D.add(Flatten())
        self.D.add(Dense(1))
        self.D.add(Activation('sigmoid'))
        self.D.summary()
        return self.D
    
    #生成模型
    def generator(self):
        if self.G:
            return self.G
        self.G = Sequential()
        dropout = 0.4
        depth = 64*8
        # 初始平面大小设置
        dim = 6
        
        # 全连接层,100个的随机噪声数据,6*6*256个神经网络
        '''
        规范化BatchNormalization:该层在每个batch上将前一层的激活值重新规范化,
        即使得其输出数据的均值接近0,其标准差接近1
        移动均值和移动方差的动量。
        https://keras.io/zh/layers/normalization/
        
        '''
        self.G.add(Dense(dim*dim*depth,input_dim=100))
        self.G.add(BatchNormalization(momentum=0.9))
        self.G.add(Activation('relu'))
        #把1维的向量变成3维数据(6*6*256)
        self.G.add(Reshape((dim, dim, depth)))
        self.G.add(Dropout(dropout))
        
        # 用法和 MaxPooling2D 基本相反,比如:UpSampling2D(size=(2, 2))
        # 就相当于将输入图片的长宽各拉伸一倍,整个图片被放大了
        # 上采样,采样后得到数据格式(12,12,256)
        self.G.add(UpSampling2D())
        # 转置卷积,得到数据格式(12,12,128)
        self.G.add(Conv2DTranspose(int(depth/2), 5, padding='same'))# 通过计算可以发现这个并不改变形状
        self.G.add(BatchNormalization(momentum=0.9))
#         self.G.add(BatchNormalization(momentum=0.8))
        self.G.add(Activation('relu'))
        
        # 上采样,采样后得到数据格式(24,24,128)
        self.G.add(UpSampling2D())
        # 转置卷积,得到数据格式(24,24,64)
        self.G.add(Conv2DTranspose(int(depth/4), 5, padding='same'))
        self.G.add(BatchNormalization(momentum=0.9))
#         self.G.add(BatchNormalization(momentum=0.8))
        self.G.add(Activation('relu'))
        
        # 上采样,采样后得到数据格式(48,48, 128)
        self.G.add(UpSampling2D())
        # 转置卷积,得到数据格式(48,48,32)
        self.G.add(Conv2DTranspose(int(depth/8), 5, padding='same'))
        self.G.add(BatchNormalization(momentum=0.9))
#         self.G.add(BatchNormalization(momentum=0.8))
        self.G.add(Activation('relu'))
        
        # 上采样,采样后得到数据格式(96,96, 32)
        self.G.add(UpSampling2D())
        # 转置卷积,得到数据格式(96,96,3) 
        self.G.add(Conv2DTranspose(self.channel, 5, padding='same'))
        self.G.add(Activation('tanh'))
        self.G.summary()
        return self.G
    
    # 定义判别模型
    def discriminator_model(self):
        if self.DM:
            return self.DM
        #定义优化器
        optimizer = RMSprop(lr=0.0002, decay=6e-8)
        #构建模型
        self.DM = Sequential()
        self.DM.add(self.discriminator())
        self.DM.compile(loss='binary_crossentropy', optimizer=optimizer, metrics=['accuracy'])
        return self.DM
    
    # 定义对抗模型
    def adversarial_model(self):
        if self.AM:
            return self.AM
        # 定义优化器
        optimizer = RMSprop(lr=0.0001, decay=3e-8)
        #构建模型
        self.AM = Sequential()
        # 生成器
        self.AM.add(self.generator())
        # 判别器
        self.AM.add(self.discriminator())
        self.AM.compile(loss='binary_crossentropy', optimizer=optimizer, metrics=['accuracy'])
        return self.AM
    
class MNIST_DCGAN(object):
    
    
    
    def __init__(self):
        self.img_rows = 96
        self.img_cols = 96
        self.channel = 3
        
#         (x_train,y_train),(x_test,y_test) = mnist.load_data()
#         #(60000,28,28)
#         self.x_train = x_train/255.0
#         #改变数据格式(samples, rows, cols, channel)(60000,28,28,1)
#         self.x_train = self.x_train.reshape(-1, self.img_rows, self.img_cols, 1).astype(np.float)
        
    
        img_names = os.listdir(os.path.join('faces'))
        img_names = np.array(img_names)
        idx = np.random.randint(0, img_names.shape[0], 128)
        img_names = img_names[idx]
        img = []
        
            # 把图片读取出来放到列表中
        for i in range(len(img_names)):
            images = image.load_img(os.path.join('faces', img_names[i]), target_size=(96, 96))
            x = image.img_to_array(images)
            x = np.expand_dims(x, axis=0)
            img.append(x)
            # print('loading no.%s image' % i)
            
        # 把图片数组联合在一起

        x_train = np.concatenate([x for x in img])
        self.x_train = x_train / 127.5 - 1.
        
            
        self.x_train = self.x_train.reshape(-1, 96,96, 3)

       
        
        # 实例化DCGAN
        self.DCGAN = DCGAN()
        #定义判别器模型
        self.discriminator =  self.DCGAN.discriminator_model()
        # 定义对抗模型
        self.adversarial = self.DCGAN.adversarial_model()
        # 定义生成器
        self.generator = self.DCGAN.generator()
        
    # 训练模型
    def train(self, train_steps=2000, batch_size=256, save_interval=0):
        noise_input = None
        if save_interval>0:
            #生成16个100维的噪声数据
            noise_input = np.random.uniform(-1.0, 1.0, size=[16, 100])
        
        for i in range(train_steps):
        # 训练判别器,提升判别器的能力
            # 随机得到一个batch的图片数据
            images_train = self.x_train[np.random.randint(0, self.x_train.shape[0], size=batch_size), :, :, :]
            # 随机生成一个batch的噪声数据
            noise = np.random.uniform(-1.0, 1.0, size=[batch_size, 100])
            # 生成伪造的图片数据
            images_fake = self.generator.predict(noise)
            # 合并一个batch的真实图片和一个batch的伪造图片
            x = np.concatenate((images_train, images_fake))
            #定义标签,真实的数据的标签为1,伪造的数据的标签为0
            y = np.ones([2*batch_size, 1])
            y[batch_size:, :] = 0
            #把数据放到判别器中进行判断
            d_loss = self.discriminator.train_on_batch(x, y)
            
        #训练对抗模型,提升生成器的造价能力
            # 标签都定义为1
            y = np.ones([batch_size, 1])
            # 生成一个batch的噪音数据
            noise = np.random.uniform(-1.0, 1.0, size=[batch_size, 100])
            #训练对抗模型
            a_loss = self.adversarial.train_on_batch(noise, y)
            
            #打印判别器的loss和准确率,以及对抗模型的loss和准确率
            log_mesg = "%d: [D loss: %f, acc: %f]" % (i, d_loss[0], d_loss[1])
            log_mesg = "%s  [A loss: %f, acc: %f]" % (log_mesg, a_loss[0], a_loss[1])
            print(log_mesg)
            #如果需要保存图片
            if save_interval>0:
                # 每save_interval次保存一次
                if (i+1)%save_interval==0:
                    self.plot_images(step=(i+1))

                    
    #保存图片
    def plot_images(self, step):
        r, c = 5, 5
        noise = np.random.normal(0, 1, (r * c, 100))  #高斯分布,均值0,标准差1,size= (5*5, 100)
        gen_imgs = self.generator.predict(noise)

        # Rescale images 0 - 1
        gen_imgs = 0.5 * gen_imgs + 0.5

        fig, axs = plt.subplots(r, c)
        cnt = 0   #生成的25张图 显示出来
        for i in range(r):
            for j in range(c):
                axs[i,j].imshow(gen_imgs[cnt, :,:,:])
                axs[i,j].axis('off')
                cnt += 1
        fig.savefig("images/mnist_%d.png" % step)
        plt.close()
            
            
# 实例化网络的类
mnist_dcgan = MNIST_DCGAN()
# 训练模型
mnist_dcgan.train(train_steps=30000, batch_size=128, save_interval=50)

其实核心就是下面这个代码,当然需要导入相应的包

img_names = os.listdir(os.path.join('faces'))# 这个faces就是数据保存的文件夹,我们可以在程序代码的相同文件夹下创建这个文件,这样就不需要写数据路径了
        img_names = np.array(img_names)
        idx = np.random.randint(0, img_names.shape[0], 128)
        img_names = img_names[idx]
        img = []
        
            # 把图片读取出来放到列表中
        for i in range(len(img_names)):
            images = image.load_img(os.path.join('faces', img_names[i]), target_size=(96, 96))# 这边的face也是的
            x = image.img_to_array(images)
            x = np.expand_dims(x, axis=0)
            img.append(x)
            # print('loading no.%s image' % i)
            
        # 把图片数组联合在一起

        x_train = np.concatenate([x for x in img])
        self.x_train = x_train / 127.5 - 1.
        
            
        self.x_train = self.x_train.reshape(-1, 96,96, 3)# 这一步主要是对图像进行形状的变化,跟导入数据集已经没有什么关系了

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(kreas笔记)