Keras新手详细入门教程:从数据集构建到服务器运行

一、前言

  研一进入实验室这两个月以来,小弟按照老板的吩咐学习深度学习方面的知识,期间看了不少大牛们的教学视频(吴恩达、李宏毅、李飞飞等),也把mnist手写数据集跑了一跑,当时还以为自己入了门。

  直到最近,老板说要检验我的学习成果,扔下来一个真假脸训练集(近50000张真人脸,近40000张合成人脸、简称假脸),让我训练一个网络把他们分好类。那么实际上就是解决一个二分类问题。

  不做不知道,一做发现自己其实还什么都不会orz。

二、数据集的构建

  mnist手写识别人称深度学习界的“helloworld”,简单到你都不用去考虑怎么构建数据集和标签集,直接一句就搞定了

import keras
from keras.datasets import mnist
(train_images,train_labels),(test_images,test_labels)=mnist.load_data()

然而我的数据都放在文件夹中,甚至文件夹里面还有各个子文件夹(例如:训练集/真脸/张三,训练集/真脸/李四,训练集/假脸/王五),那么我们的第一步,就是学会如何遍历所有文件夹(包括子文件夹)中的所有图片。

1.os.walk()

https://blog.csdn.net/qq_38356397/article/details/103159089我归类到别的地方

这个函数是真的好用,可以很方便地遍历根文件夹root里的所有文件,包括root下面的所有子文件夹dirs,以及所有子文件夹里面的所有文件files,返回他们各自的名字。

举个栗子:我现在有一个文件夹,长这个样子

#例子一
import os
root_path="D:\\root_path"
for x in os.walk(root_path):
    print(x)

运行结果:

我们可以看到,os.walk返回一系列的元祖,每个元祖代表一次遍历。每个元祖里面存放着三个东西:

第一个是字符串,存放当前遍历的文件夹路径;

第二个是一个列表,列表里以字符串的形式存放当前遍历的文件夹中,所有子文件夹的名字

第三个是一个列表,列表里以字符串的形式存放当前遍历的文件夹中,除子文件以外,存放的文件的名字

显然,在D:/root_path里,只有两个文件夹,没有其他文件,所以为空。

以此类推,直到遍历完所有子文件夹中的所有文件。

 

一个更加实用的遍历方法:

#遍历方法
import os
root_path="D:\\root_path"
for root,dirs,files in os.walk(root_path):
    for file in files:
        #这里可以对每个文件做你想做的操作
        print("遍历"+file)

运行结果:

我们就可以利用这个os.walk()函数,将我们庞大的数据集分好类别,放到各自的文件夹中。

# 把original_dir路径下所有图片(包括子文件夹中的),重命名复制到destination_dir中,合并到一起
def gather_data(flag, original_dir, destination_dir):
    counter_name = 0  # 计数器
    for root, dirs, files in os.walk(original_dir):  # 遍历所有数据
        for file in files:
            counter_name = counter_name + 1
            file_full_path = os.path.join(root, file)  # 完整路径
            # shutil.copy(file_full_path,destination_dir)#复制文件
            file_new_path = os.path.join(destination_dir, file)
            file_rename_path = os.path.join(destination_dir, flag + str(counter_name) + ".jpg")
            # os.rename(file_new_path, file_rename_path)#重命名

    print("Gather Data Successfully!")
    return counter_name  # 返回读了多少个文件

为什么要这样分类放呢?是为了方便使用keras的批量图片生成器generator,从而解决数据过多而内存不足的问题。

2.keras的批量图片生成器generator

https://blog.csdn.net/qq_38356397/article/details/103164266文章归类

还记得在跑mnist的时候,训练集里有60000张黑白图片,每张图片为28*28,把所有图片塞到一个矩阵里面一点问题都没有。

现在就不一样了,我的数据集里大概有90000张彩色图片,图片的size就是384*512*3,这远远大于mnist的训练集,如果同时将它们塞进一个矩阵里,那么内存估计够呛。

所以,我们要学会利用keras里面的批量图片生成器generator,一批一批的读图片放进去训练。下面我写一个函数,把图片批量读取和模型的训练都放在这个函数里面。

from keras.preprocessing.image import ImageDataGenerator
# 喂入数据训练
#函数参数(定义的模型,训练集存放文件夹路径,测试集存放文件夹路径,
#batch_size大小,跑多少个epoch,训练集有多少张图片,模型保存路径)
def model_train(model, destination_train_dir, destination_test_dir, 
batch_size_set, epoch_set, train_all_counter,model_save_name):
    # 构建生成器,从文件夹中循环读取训练集和测试集
    #训练集生成器,参数rescale将图片像素归一化,结合sigmoid激活函数效果更好
    train_datagen = ImageDataGenerator(rescale=1. / 255)
    #测试集生成器
    test_datagen = ImageDataGenerator(rescale=1. / 255)
    #训练集大小/batch大小=每个epoch要读多少次数据
    steps_per_epoch_set = math.ceil(train_all_counter / float(batch_size_set))
    #测试集大小/batch大小
    validation_steps_set = math.ceil((test_all_counter / float(batch_size_set)))

    #生成训练batch(一般放四个参数:训练集文件夹路径,每张图片的size,每个batch的大小,以及标签的类型)
    train_generator = train_datagen.flow_from_directory(
        destination_train_dir,
        target_size=(384, 512),
        batch_size=batch_size_set,
        class_mode='binary'
    )
    # 生成测试batch
    validation_generator = test_datagen.flow_from_directory(
        destination_test_dir,
        target_size=(384, 512),
        batch_size=batch_size_set,
        class_mode='binary'
    )
    # ---------------------------------------------------------------------------------------------------------------------------------
    # 训练(五个参数:训练集生成器,训练每个epoch要抽取多少次图片,多少个epoch,测试集生成器,测试要抽取多少次数据)
    history = model.fit_generator(
        train_generator,
        steps_per_epoch=steps_per_epoch_set,
        epochs=epoch_set,
        validation_data=validation_generator,
        validation_steps=validation_steps_set
    )
    # ---------------------------------------------------------------------------------------------------------------------------------
    # 保存模型
    model_path = os.path.join(model_dir, model_save_name)
    model.save(model_path)
    return history

参考:https://blog.csdn.net/qq_38356397/article/details/103164266

我们重点关注 train_generator = train_datagen.flow_from_directory(…)生成训练集batch的这一段,像代码中那样依次把参数都填进去就可以了生成相应训练batch。

需要强调的是,你要解决n分类问题,就要在destination_train_dir这个文件夹(你自己设置,叫什么名字都可以)中建立n个子文件夹,并把你训练数据中的n个类别的数据分别放到这n个文件夹中,每一个子文件夹都会被推断为一个新的类别。

同时class_mode这个参数要设置成"categorical", "binary", "sparse"或None之一. 该参数决定了返回的标签数组的形式, "categorical"会返回2D的one-hot编码标签,"binary"返回1D的二值标签."sparse"返回1D的整数标签,如果为None则不返回任何标签。

例如我是二分类问题,所以训练数据集文件夹中又分了两个子文件夹,利用os.walk()遍历我的原数据集,并放到这些子文件夹里,class_mode设置成'binary',生成器就会按照根据我设置的参数,循环生成1个batch的训练集,并且已经为它打好了分类标签。

接下来要做的,就是同样套路设置测试集生成器,以及将这两个生成器喂入model.fit_generator(…)训练即可。

当然,我们也可以对同一堆数据集,利用train_test_split方法自动划分成训练集和测试集,这里不再加以描述。

三、模型定义

这一部分相信无需多说了,相信各位从书籍上亦或是视频上,对这一块都有一个大致的认识。

例如说先搞几个卷积层,每个卷积层后面搞个maxpooling,卷积完之后再搞个全连接层。

诶欠拟合?那把层数加深加宽吧。诶过拟合?加个dropout吧。

搞搞搞,最后二分类问题准确率约等于0.5

这是我随便搭的网络的结果↓

这是我利用毕生所学(两个月)修改网络的结果↓

噢!神奇的神经网络!

四、服务器的使用

好了,数据集准备好了,网络模型也搭好了,是骡子是马就差把它拉出来遛一遛了。然而单凭我打撸都会跳帧的小霸王,是无论如何也跑不起来这个网络的,这个时候我们就要把网络放到实验室的服务器里面去跑了。

进实验室之前,我是从来没有摸过服务器这么高大上的东西的,感觉可能有人会有和我当初一样的疑惑,我就再把服务器使用的这部分再介绍一下。

1.服务器到底是啥

最简单粗暴的理解,服务器就是一台cpu、gpu都很棒的电脑,跑东西速度比自己的小霸王快很多。一般放在实验室的某个角落,样子不像电脑的样子。可以通过你自己的电脑远程操纵服务器,把东西放上去运行。登上去之后一般就是linux系统的大黑框terminal,通过linux指令运行。

2.怎么连上实验室的服务器

首先,我们要下载一个软件,叫MobaXterm,在这个软件上可以连接到服务器,通过指令操作服务器。

下载地址:https://mobaxterm.mobatek.net/download.html免费家庭版应该够用了

打开软件,点击左上角的Session

再点SSH,在下面的Remote host 填服务器地址,Specify username填你的账号名(用服务器之前找管理服务器的师兄师兄帮你申请一个账号和设置密码)。

再点OK就可以看到迷人的大黑框了,提示你输入密码。你输入的时候是没有反应的,不会有****的提示,不要以为你键盘坏了:)

进入之后就是这个样子啦:(他们说有些东西不能露出来)

左边就是服务器里面的文件夹,可以按照权限操纵文件,新建个文件夹放代码之类的。

右边就是linux的大黑框,跑代码先 “cd 路径” 到你放代码的文件夹里,再“python3 代码文件名.py”跑代码就行啦

3.服务器文件与本机文件交互

上面的MobaXterm是用来操纵服务器跑代码的,但是在文件上传和下载这方面还不是很方便,咱们再下载一个专门用来处理文件的软件:WinSCP

下载地址:https://winscp.net/eng/download.php

使用方法和MobaXterm一样,登陆之后左边就是你本机的文件夹,右边就是服务器的文件夹,这样上传和下载的时候就很方便啦~例如代码有大改动的时候,在本机上改完,然后在软件上从左边拖到右边,替换掉原来的就OK了。

4.服务器空闲查询

要注意的是,这台服务器是整个实验室的人一起用的,那么当有别的人在跑程序的时候,就可能没有空间给你跑了。

那怎么知道有没有空余的显卡可以拿来跑呢?

可以使用linux命令nvidia-smi,直接在大黑框那个界面输入即可。

最左边的0123表示四块显卡,中间的Memory—Usage表示每块显卡的使用情况,例如现在显卡2是空闲的,013都在跑东西,又或者直接看下面的Processes,发现013都有程序在跑,2没有,我们就可以用gpu2来跑程序了。

怎么指定呢?在你python程序的最前面,加上这句就可以了。每次跑之前看哪块空着,修改数字即可。

import os 
os.environ['CUDA_VISIBLE_DEVICES']='2'

五、总结

标题的新手说的就是我自己,本文就是总结近段时间学到的觉得比较有用的东西,希望能够帮助到和我之前有同样疑惑的朋友。

 

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值