IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> 机器学习——caffe从数据准备到模型训练和预测全流程-9 -> 正文阅读

[人工智能]机器学习——caffe从数据准备到模型训练和预测全流程-9

前言

不仅仅需要知道这个图片的内容是什么,
也需要让机器标注出图片的各部分内容,比如猫,狗,人,车等用框框标注出来,需要返回各个内容的坐标
在做人脸识别时就需要知道人脸的位置以及各个特征点的位置,这都是必要的

新的工具——无代码神经网络

caffe!!!你没看错,不需要写代码,只需要定义一些配置文件,真正做到了设计神经网络就能让他跑起来的地步
四个步骤:
转换数据(设置数据位置以及数据格式)
定义网络(编辑prototxt) 设计卷积层
定义求解器(编辑prototxt) 即设置学习率等超参数
训练(使用预先训练过的权重)(运行脚本)

需要定义四个配置文件:
数据源存储的地方BLOB,数据块配置文件
层配置文件,即数据层,卷积层等等,都是一层层支配的
神经图层配置文件
求解器配置文件
在这里插入图片描述
图片配置文件案例,先了解流程:
定义神经图层,直接从第二步开始了
包含数据层,卷积层,全连接层
在这里插入图片描述
定义求解器,第三步:
超参数
在这里插入图片描述
第四步,训练…
有win和linux两个版本,我用win,无他,方便尔
在这里插入图片描述

也就是说定义两个配置文件就能迅速的看到设计的神经网络的表现了,只是一些参数配置操作
事实上有很多预置的配置文件都是非常有名的,有时并不需要你亲自设计神经网络层…
如果样本合适,抓一个跑一跑,正确率也能达到95%以上左右,呵呵哒
模型动物园
在这里插入图片描述

caffe从准备数据到模型预测流程

1·准备数据

使用keras做数据增强,比opencv简便,数据增强就是图片平移,旋转,反转啥的,能把原数数据扩容几倍
需要安装两个依赖
在这里插入图片描述

keras在tensorflow上做了一层封装,使用会更加简便一些。这里是图像增强的api
在这里插入图片描述

2·接下来说如何将图片文件打包成lmdb格式

格式转换的4个必要条件:
  (1)编译好Caffe,而且convert_imageset.exe存在;
  (2)需要被转换的图像和目录
  (3)在将图像转换为lmdb格式之前,首先生成两个标签文件train.txt和val.txt(具体格式见下文);
  (4)运行编辑修改好的create_imagenet.sh(最好将其制到你的项目文件夹下,不修改原始文件)生成lmdb文件。
  开始吧!
原始数据如图
在这里插入图片描述
train是训练用的,val是测试用的
train内部结构
在这里插入图片描述
0里面是各种人脸图片,1里面则是不包含人脸的图片
val内部结构
在这里插入图片描述
仔细看就会发现,里面的图片用名字标注了是否包含人脸,因为是测试数据,就不需要分成01文件夹了,根据名字直接判别即可
然而如果想要打包成lmdb格式,仅仅有train和val训练和测试文件数据还不行,完整的原始数据应该是
在这里插入图片描述
在这里插入图片描述
多出来train.txt,和val.txt,这两个是从图片数据中提取出来的标签文件
train.txt内容结构如下:
在这里插入图片描述
每一行代表着,这是0文件夹下名字为xxxx的图片文件,标签是0

val.txt文件如图:
在这里插入图片描述
因为没有文件夹区分,所以直接是文件名,标签格式
train.txt和val.txt需要我们从图片数据中生成,这是python代码,你只需要修改实际路径即可

import os
import random
#数据集根目录所在路径
root_data_path = r"C:\Users\Administrator.DESKTOP-KMH7HN6\Downloads\li_test_net\my_face_detect\data_set"
#输出的TXT文件路径
traintxt_path = root_data_path + "\\" + "train.txt"
valtxt_path = root_data_path + "\\" + "val.txt"

#如果存在之前生成的TXT文件,先把它们删除
if os.path.exists(traintxt_path):
    os.remove(traintxt_path)
if os.path.exists(valtxt_path):
    os.remove(valtxt_path)
#返回数据集文件夹下的子文件夹
filenames = os.listdir(root_data_path)    #["train", "val"]

#打开要存储的TXT文件
file_train = open(traintxt_path, "w")
file_val = open(valtxt_path, "w")
train_list=[]
val_list=[]
if len(filenames) > 0:
    for fn in filenames:
        #数据集根目录下的子文件夹路径,train和val的绝对路径
        full_filename = os.path.join(root_data_path, fn)

        # 判断是训练集文件夹,还是验证集文件夹
        if fn == "train":
            #找出训练集文件夹下的子文件夹名字,是每个类别的文件夹,0表示狗,1表示猫
            file = os.listdir(full_filename)   #["0", "1"]
            for name in file:
                #获得train文件夹下的子文件夹“0”和“1”的绝对路径
                temp = os.path.join(full_filename, name)
                for img in os.listdir(temp):    #分别遍历两个文件夹["0", "1"]下的所有图像
                    #将图像的信息写入到train.txt文件
                    # file_train.write(name + "/" + img + " " + name + "\n")
                    train_list.append(name + "/" + img + " " + name + "\n")
        elif fn == "val":        #当进入到val文件夹后
            for img in os.listdir(full_filename):   #遍历所有的图像
                category = img.split('_')           #对图像的名字进行分割,返回的是一个列表
                if category[1] == "nonface":            #当分割的结果可以判断是dog时,类别是“0”
                    # file_val.write(img + " " + "1" + "\n")
                    val_list.append(img + " " + "1" + "\n")
                else:           #当分割的结果可以判断是cat时,类别是“1”
                    # file_val.write(img + " " + "0" + "\n")
                    val_list.append(img + " " + "0" + "\n")

#打乱文件的顺序
#打乱列表顺序,将打乱的列表输出为新的train,val文件
def random_order(mylist):
    newlist = []
    all_len=len(mylist)
    for i in range(all_len):
        if mylist:
            len1 = len(mylist)
            myindex = random.randint(0, len1 - 1)
            myval = mylist[myindex]
            newlist.append(myval)
            mylist.remove(mylist[myindex])
    mynewcontent = ""
    for i in newlist:
        mynewcontent = mynewcontent + i
    return mynewcontent
file_train.write(random_order(train_list))
file_val.write(random_order(val_list))
file_train.close()
file_val.close()

文件生成后,编辑sh即可
caffe-windows\examples\imagenet下有示例文件create_imagenet.sh
含义如下:

#!/usr/bin/env sh
# Create the imagenet lmdb inputs    #创建LMDB格式的文件输入
# N.B. set the path to the imagenet train + val data dirs    #为train和val数据目录设置路径

EXAMPLE=C:/Users/Administrator/Desktop/data_set                   #生成模型训练数据的文件夹,即create_imagenet.sh(这里名字可以修改)所在文件夹。
DATA=C:/Users/Administrator/Desktop/data_set                      #python脚本处理完的数据存储路径,也就是train.txt和val.txt的存储路径
TOOLS=D:/program_files/caffe/caffe-windows/Build/x64/Release       #caffe的工具库,找到自己的编译过的convert_imageset.exe所在的位置

TRAIN_DATA_ROOT=C:/Users/Administrator/Desktop/data_set/train/      #待处理的训练数据的路径
VAL_DATA_ROOT=C:/Users/Administrator/Desktop/data_set/val/          #待处理的验证数据的路径

# Set RESIZE=true to resize the images to 256x256. Leave as false if images have
# already been resized using another tool.
RESIZE=true                                 #是否对图片进行resize操作,如果是设置为True
if $RESIZE; then
  RESIZE_HEIGHT=256                           #resize的尺寸是256*256
  RESIZE_WIDTH=256
else
  RESIZE_HEIGHT=0
  RESIZE_WIDTH=0
fi

if [ ! -d "$TRAIN_DATA_ROOT" ]; then
  echo "Error: TRAIN_DATA_ROOT is not a path to a directory: $TRAIN_DATA_ROOT"
  echo "Set the TRAIN_DATA_ROOT variable in create_imagenet.sh to the path" \
       "where the ImageNet training data is stored."
  exit 1
fi

if [ ! -d "$VAL_DATA_ROOT" ]; then
  echo "Error: VAL_DATA_ROOT is not a path to a directory: $VAL_DATA_ROOT"
  echo "Set the VAL_DATA_ROOT variable in create_imagenet.sh to the path" \
       "where the ImageNet validation data is stored."
  exit 1
fi


echo "if train.txt and val.txt are exist in EXAMPLE dir. clear all"
#删除已存在的lmdb格式文件,若在已存在lmdb格式的文件夹下再添加lmdb文件,会出现错误
rm -rf $EXAMPLE/train_lmdb
rm -rf $EXAMPLE/val_lmdb


echo "Creating train lmdb..."

GLOG_logtostderr=1 $TOOLS/convert_imageset \     #调用convert_imageset进行格式转换
    --resize_height=$RESIZE_HEIGHT \             #将图片调整到固定尺寸
    --resize_width=$RESIZE_WIDTH \
    --shuffle \                                  #打乱图像的顺序
    $TRAIN_DATA_ROOT \
    $DATA/train.txt \                           #这里的DATA是存放train.txt的路径
    $EXAMPLE/train_lmdb                         #这里修改输出的训练集的LMDB的名称

echo "Creating val lmdb..."

GLOG_logtostderr=1 $TOOLS/convert_imageset \     #调用convert_imageset进行格式转换
    --resize_height=$RESIZE_HEIGHT \             #将图片调整到固定尺寸
    --resize_width=$RESIZE_WIDTH \
    --shuffle \                                  #打乱图像的顺序
    $VAL_DATA_ROOT \
    $DATA/val.txt \                             #这里的DATA是存放val.txt的路径
    $EXAMPLE/val_lmdb                           #这里修改输出的验证集的LMDB的名称

echo "Done."   read                                             #最后加一行read,可以让窗口暂停等待,相当于pause。

复制自带的create_imagenet.sh文件到你的工程目录下,根据需要修改内容,比如我的

#!/usr/bin/env sh
# Create the imagenet lmdb inputs    #创建LMDB格式的文件输入
# N.B. set the path to the imagenet train + val data dirs    #为train和val数据目录设置路径

EXAMPLE=C:/Users/Administrator.DESKTOP-KMH7HN6/Downloads/li_test_net/my_face_detect/data_set    #生成模型训练数据的文件夹,即create_imagenet.sh(这里名字可以修改)所在文件夹。
DATA=C:/Users/Administrator.DESKTOP-KMH7HN6/Downloads/li_test_net/my_face_detect/data_set                     #python脚本处理完的数据存储路径,也就是train.txt和val.txt的存储路径
TOOLS=C:/Users/Administrator.DESKTOP-KMH7HN6/Downloads/Compressed/caffer_data/caffe-windows/scripts/build/tools/Release       #caffe的工具库,找到自己的编译过的convert_imageset.exe所在的位置

TRAIN_DATA_ROOT=C:/Users/Administrator.DESKTOP-KMH7HN6/Downloads/li_test_net/my_face_detect/data_set/train/      #待处理的训练数据的路径
VAL_DATA_ROOT=C:/Users/Administrator.DESKTOP-KMH7HN6/Downloads/li_test_net/my_face_detect/data_set/val/          #待处理的验证数据的路径

# Set RESIZE=true to resize the images to 256x256. Leave as false if images have
# already been resized using another tool.
RESIZE=true
if $RESIZE; then
  RESIZE_HEIGHT=227
  RESIZE_WIDTH=227
else
  RESIZE_HEIGHT=0
  RESIZE_WIDTH=0
fi

if [ ! -d "$TRAIN_DATA_ROOT" ]; then
  echo "Error: TRAIN_DATA_ROOT is not a path to a directory: $TRAIN_DATA_ROOT"
  echo "Set the TRAIN_DATA_ROOT variable in create_imagenet.sh to the path" \
       "where the ImageNet training data is stored."
  exit 1
fi

if [ ! -d "$VAL_DATA_ROOT" ]; then
  echo "Error: VAL_DATA_ROOT is not a path to a directory: $VAL_DATA_ROOT"
  echo "Set the VAL_DATA_ROOT variable in create_imagenet.sh to the path" \
       "where the ImageNet validation data is stored."
  exit 1
fi

echo "Creating train lmdb..."

GLOG_logtostderr=1 $TOOLS/convert_imageset \
    --resize_height=$RESIZE_HEIGHT \
    --resize_width=$RESIZE_WIDTH \
    --shuffle \
    $TRAIN_DATA_ROOT \
    $DATA/train.txt \
    $EXAMPLE/face_train_lmdb

echo "Creating val lmdb..."

GLOG_logtostderr=1 $TOOLS/convert_imageset \
    --resize_height=$RESIZE_HEIGHT \
    --resize_width=$RESIZE_WIDTH \
    --shuffle \
    $VAL_DATA_ROOT \
    $DATA/val.txt \
    $EXAMPLE/face_val_lmdb

echo "Done."

然而windows不能运行sh文件,安装一下git就行了,将他加入系统变量,双击sh文件就默认git运行了
在这里插入图片描述
注意事项
  (1)注意windows系统中路径问题,复制的路径是“\”,在程序中需要的是“/”,注意对其修改,生成的train.txt和val.txt中的路径也是“/”。
  (2)必须保证你的caffe编译成功
  (3)修改convert_imageset.sh时,一定要注意路径问题,这里就是配置路径的很容易出错(具体请看上面的详细过程)。
  (4)图像的名字中不要出现空格,否则会有问题(深刻的痛)。
  (5)生成的train.txt文件中的图像路径问题:路径从train文件夹之后开始写,不包括train文件夹名称。
  (6)如果之前生成过文件(不管是train.txt和val.txt,还是train_lmdb和val_lmdb),想重新生成,最好先删除之前的,有可能会有错误。

至此,lmdb数据已经生成完毕
在这里插入图片描述

3·制作hdf5数据格式

lmdb可以解决图像分类问题,0或者1
然而如果想要实现图像检测问题,比如在一张人脸图像上找到眼睛的位置,嘴的位置,返回坐标,就需要多目标检测
数据格式如下
在这里插入图片描述
一张图片共标记了五个位置,每两组数据作为一个x和y坐标
11 78左眼 62 71右眼 84 65 鼻子 26 51 左嘴角 46 89右嘴角
在这里插入图片描述
三张图片

最终的目标如图
将数据打包成h5格式,h5文件里包含了数据的内容和标签
之所以分为多个h5文件,是因为日常使用时不希望将所有的数据打包在一起,否则单个数据文件过大不是一件好事
trainlist.txt和testlist.txt里记录的是h5的文件名,相当于将h5文件分为了训练集和验证集
在这里插入图片描述

在这里插入图片描述
只要有图片文件和标签文件,即可使用如下代码生成
每行代码含义已经注明,根据需要修改

import h5py
import os
import cv2
import math
import numpy as np
import random
import re

root_path = r"C:\Users\Administrator.DESKTOP-KMH7HN6\Downloads\li_test_net\my_face_detect\hdf5\image"

with open(r"C:\Users\Administrator.DESKTOP-KMH7HN6\Downloads\li_test_net\my_face_detect\hdf5\hdf5.txt", 'r') as f:
    lines = f.readlines()

num = len(lines)
#打乱样本顺序
random.shuffle(lines)

base_path_h5=r"C:\Users\Administrator.DESKTOP-KMH7HN6\Downloads\li_test_net\my_face_detect\hdf5\h5"
imgAccu = 0
#制造出一个可以容纳图像数据和label的矩阵
imgs = np.zeros([num, 3, 224, 224])
labels = np.zeros([num, 10])
for i in range(num):
    #将图像读取过来
    line = lines[i]
    segments = re.split('\s+', line)[:-1]
    print(segments[0])
    img = cv2.imread(os.path.join(root_path, segments[0]))
    img = cv2.resize(img, (224, 224))
    #caffe是c*h*w,   opencv是h*w*c,这里处理后可以将通道提前
    img = img.transpose(2,0,1)
    #指定数据如何存入imgs矩阵中
    imgs[i,:,:,:] = img.astype(np.float32)
    #因为图片大小变化,标签坐标也要缩放
    for j in range(10):
        labels[i,j] = float(segments[j+1])*224/256
#指定每次h5打包多少文件
batchSize = 1
batchNum = int(math.ceil(1.0*num/batchSize))
#对数据的预处理,希望数据围绕零点分布,
imgsMean = np.mean(imgs, axis=0)
#imgs = (imgs - imgsMean)/255.0
labelsMean = np.mean(labels, axis=0)
labels = (labels - labelsMean)/10

if os.path.exists('trainlist.txt'):
    os.remove('trainlist.txt')
if os.path.exists('testlist.txt'):
    os.remove('testlist.txt')
comp_kwargs = {'compression': 'gzip', 'compression_opts': 1}
for i in range(batchNum):
    #求出当前batchsize的起止地址
    start = i*batchSize
    end = min((i+1)*batchSize, num)
    #开始写入文件
    if i < batchNum-1:
        filename = r'C:\Users\Administrator.DESKTOP-KMH7HN6\Downloads\li_test_net\my_face_detect\hdf5\h5\train{0}.h5'.format(i)
    else:
        filename = r'C:\Users\Administrator.DESKTOP-KMH7HN6\Downloads\li_test_net\my_face_detect\hdf5\h5\test{0}.h5'.format(i-batchNum+1)
    print(filename)
    #gpu运算一般都要求float32形式,/255是为了归一化,将rgb像素缩小到0-1范围内,运行后,数据和标签就变成h5格式了
    with h5py.File(filename, 'w') as f:
        f.create_dataset('data', data = np.array((imgs[start:end]-imgsMean)/255.0).astype(np.float32), **comp_kwargs)
        f.create_dataset('label', data = np.array(labels[start:end]).astype(np.float32), **comp_kwargs)
#将生成的h5文件路径写入
    if i < batchNum-1:
        with open(r'C:\Users\Administrator.DESKTOP-KMH7HN6\Downloads\li_test_net\my_face_detect\hdf5\h5\trainlist.txt', 'a') as f:
            f.write(os.path.join(base_path_h5, 'train{0}.h5').format(i) + '\n')
    else:
        with open(r'C:\Users\Administrator.DESKTOP-KMH7HN6\Downloads\li_test_net\my_face_detect\hdf5\h5\testlist.txt', 'a') as f:
            f.write(os.path.join(base_path_h5, 'test{0}.h5').format(i-batchNum+1) + '\n')

imgsMean = np.mean(imgsMean, axis=(1,2))
with open('mean.txt', 'w') as f:
    f.write(str(imgsMean[0]) + '\n' + str(imgsMean[1]) + '\n' + str(imgsMean[2]))

4·设置网络图层参数

无代码开始了,只需要配置神经网络图层的参数即可
即使用脚本编写神经图层参数控制即可,然而如果脚本都不想写,想让脚本自动生成呢?
设计好参数,自动生成脚本即可

import sys
# caffe_root='/home/tyd/caffe/'
# sys.path.insert(0, caffe_root+'python')
from caffe import layers as L
from caffe import params as P
import caffe

def lenet(lmdb, batch_size):
    # our version of LeNet: a series of linear and simple nonlinear transformations
    n = caffe.NetSpec()
    #数据层,指定数据块大小,数据源,数据格式,数据缩放,ntop=2代表得到了两个输出
    n.data, n.label = L.Data(batch_size=batch_size, backend=P.Data.LMDB, source=lmdb,
                             transform_param=dict(scale=1./255), ntop=2)
    #卷积层,指定数据源,卷积核大小,卷积核数量,权重初始化方式
    n.conv1 = L.Convolution(n.data, kernel_size=5, num_output=20, weight_filler=dict(type='xavier'))
    #池化层,数据源,卷积核大小,步长,池化方式
    n.pool1 = L.Pooling(n.conv1, kernel_size=2, stride=2, pool=P.Pooling.MAX)
    #卷积层
    n.conv2 = L.Convolution(n.pool1, kernel_size=5, num_output=50, weight_filler=dict(type='xavier'))
    #池化层
    n.pool2 = L.Pooling(n.conv2, kernel_size=2, stride=2, pool=P.Pooling.MAX)

    n.ip1 = L.InnerProduct(n.pool2, num_output=500, weight_filler=dict(type='xavier'))
    n.relu1 = L.ReLU(n.ip1, in_place=True)
    n.ip2 = L.InnerProduct(n.relu1, num_output=10, weight_filler=dict(type='xavier'))
    n.loss = L.SoftmaxWithLoss(n.ip2, n.label)
    return n.to_proto()
#调用方法,自动写脚本文件
with open('lenet_auto_train.prototxt', 'w') as f:
    f.write(str(lenet(r'C:\Users\Administrator.DESKTOP-KMH7HN6\Downloads\li_test_net\minist_lmdb\mnist_train_lmdb', 64)))

with open('lenet_auto_test.prototxt', 'w') as f:
    f.write(str(lenet(r'C:\Users\Administrator.DESKTOP-KMH7HN6\Downloads\li_test_net\minist_lmdb\mnist_test_lmdb', 100)))


我们可以使用caffe预设的神经网络,根据已有的结构进行设置参数
也可以设置自己的神经网络图层
如果暂时不需要设计自己的caffe神经图层,这里可以暂略

4·1定义自己的层

确认打开配置文件注释,这里允许我们自定义神经图层

在这里插入图片描述
如果之前没有打开,重新编译caffe,才能重新拥有此功能
自己设计的图层如

name: "convolution"
input: "data"
#定义一次取出一张图片
input_dim: 1
#定义是三色图
input_dim: 3
input_dim: 100
input_dim: 100
layer {
  name: "conv"
  type: "Convolution"
  bottom: "data"
  top: "conv"
  convolution_param {
    num_output: 3
    kernel_size: 5
    stride: 1
    weight_filler {
      type: "gaussian"
      std: 0.01
    }
    bias_filler {
      type: "constant"
      value: 0
    }
  }
}
layer {
  name: 'MyPythonLayer'
  type: 'Python'
  top: 'output'
  bottom: 'conv'
  python_param {
    module: 'mypythonlayer'
#定义要调用的自己写的神经图层的名字
    layer: 'MyLayer'
#传递的参数
    param_str: "'num': 21"
  }
}

设计图层的代码

import sys
caffe_root='/home/tyd/caffe/'
sys.path.insert(0, caffe_root+'python')
import caffe
import numpy as np                                                                                                                                                       
import yaml
import cv2   
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
#神经图层的名字,这个神经图层仅仅定义了一个输入的加法操作,用来熟悉设计caffe神经图层
class MyLayer(caffe.Layer):
#数据准备
    def setup(self, bottom, top):
        self.num = yaml.load(self.param_str)["num"]
        print "Parameter num : ", self.num
#是否进行数据变换
    def reshape(self, bottom, top):
        pass
#设计前向传播,如何处理输入输出数据
    def forward(self, bottom, top):
        top[0].reshape(*bottom[0].shape)
        print bottom[0].data.shape
        print bottom[0].data
        top[0].data[...] = bottom[0].data + self.num
        print top[0].data[...]
#设计如何反向传播
    def backward(self, top, propagate_down, bottom):
        pass


#这是caffe自定义圣经图层固定的框架
net = caffe.Net('conv.prototxt',caffe.TEST)
#im = np.array(Image.open('timg.jpeg'))
im = np.array(cv2.imread('timg.jpeg'))
print im.shape
#opencv和caffe读取数据的顺序不同,opencv是(height,width,channel),caffe读取(batch_size,channel,height,width)
#不仅读取的参数顺序不同,维度也不同,需要转换,满足caffe的要求
#im_input = im[np.newaxis, np.newaxis, :, :]
im_input = im[np.newaxis, :, :]
print im_input.shape
#print im_input.transpose((1,0,2,3)).shape
#重新排列被opencv读入的输入数据的顺序
im_input2 = im_input.transpose((0,3,1,2))
print im_input2.shape
#print im_input.shape
#第一步变换数据,第二步将数据放入
net.blobs['data'].reshape(*im_input2.shape)
net.blobs['data'].data[...] = im_input2
net.forward()



4·2绘制网络结构图

计算均值,caffe的一个命令即可
指定数据源,指定均值输出位置

sudo caffe/build/tools/compute_image_mean /caffe/examples/mnist/mnist_train_lmdb /caffe_case/mean.binaryproto

将protxt神经网络脚本文件变成图片形式展现出来,更加直观
1、安装graphViz
sudo apt-get install graphviz
2 、安装pydot
sudo pip install pydot

sudo python /caffe/python/draw_net.py /caffe/examples/mnist/lenet_train_test.prototxt /caffe_case/lenet.png --rankdir=BT

第一个参数:网络模型的prototxt文件

第二个参数:保存的图片路径及名字

第二个参数:–rankdir=x , x 有四种选项,分别是LR, RL, TB, BT 。用来表示网络的方向,分别是从左到右,从右到左,从上到小,从下到上。默认为LR。
可能会报错:ImportError: cannot import name ‘_validate_lengths’
这是numpy版本不对造成的,卸载原来的numpy
重新安装

pip install numpy==1.15.0

仿照命令即可得到神经网络的结构图,拿minist测试后得到
在这里插入图片描述

5·开始训练

###训练网络

#sudo sh ./build/tools/caffe train --solver=examples/mnist/train_lenet.sh

-solver:必选参数。一个protocol buffer类型的文件,即模型的配置文件。如:
# ./build/tools/caffe train -solver examples/mnist/lenet_solver.prototxt

-gpu: 可选参数。该参数用来指定用哪一块gpu运行,根据gpu的id进行选择,如果设置为'-gpu all'则使用所有的gpu运行。如使用第三块gpu运行:
# ./build/tools/caffe train -solver examples/mnist/lenet_solver.prototxt -gpu 2

-weights:可选参数。用预先训练好的权重来fine-tuning模型,需要一个caffemodel如:
# ./build/tools/caffe train -solver examples/finetuning_on_flickr_style/solver.prototxt -weights models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel

###测试网络

# ./build/tools/caffe test -model examples/mnist/lenet_train_test.prototxt -weights examples/mnist/lenet_iter_10000.caffemodel -gpu 0 -iterations 100

time参数用来在屏幕上显示程序运行时间。显示网络图层,究竟消耗了多少时间,如:
# ./build/tools/caffe time -model examples/mnist/lenet_train_test.prototxt -iterations 10


关于gpu
# ./build/tools/caffe train -solver examples/mnist/lenet_solver.prototxt -gpu 0,1   让两块gpu工作
# ./build/tools/caffe train -solver examples/mnist/lenet_solver.prototxt -gpu all

6·生成loss曲线

绘制训练minist的loss曲线
真是滑稽,必须将loss.py放入如图其中在这里插入图片描述
因为caffe的案例文件里有很多都是相对路径写的,很容易找不到上级路径,运行caffe案例需要如此,然而自己的项目可以随意
在这里插入图片描述
代码如图,取代了脚本

import numpy as np
import matplotlib.pyplot as plt
import sys,os
# caffe_root = '/home/tyd/caffe/'  # this file should be run from {caffe_root}/examples (otherwise change this line)
# sys.path.insert(0, caffe_root + 'python')
import caffe

#caffe.set_device(0)
#如果使用gpu,也可以设置caffe.set_device(0)控制第几个设备  caffe.set_mode_gpu()
caffe.set_mode_cpu()
#把超参数传进来
solver = caffe.SGDSolver(r'C:\Users\Administrator.DESKTOP-KMH7HN6\Downloads\Compressed\caffer_data\caffe-windows\examples\mnist\lenet_solver.prototxt')


niter =1000
test_interval = 200
train_loss = np.zeros(niter)
test_acc = np.zeros(int(np.ceil(niter / test_interval)))

# the main solver loop
for it in range(niter):
    solver.step(1)  # SGD by Caffe
    
    # store the train loss
    train_loss[it] = solver.net.blobs['loss'].data
    solver.test_nets[0].forward(start='conv1')
    
    if it % test_interval == 0:
        acc=solver.test_nets[0].blobs['accuracy'].data
        print ('Iteration', it, 'testing...','accuracy:',acc)
        test_acc[it // test_interval] = acc

print (test_acc)
_, ax1 = plt.subplots()
ax2 = ax1.twinx()
ax1.plot(np.arange(niter), train_loss)
ax2.plot(test_interval * np.arange(len(test_acc)), test_acc, 'r')
ax1.set_xlabel('iteration')
ax1.set_ylabel('train loss')
ax2.set_ylabel('test accuracy')
plt.show()


7·根据模型跑文件

图中文件是模型训练好的网络结构
而model文件加上超参数则可以对新的数据进行预测
在这里插入图片描述
训练时需要数据和标签,得到caffe的model,然后使用新的数据对model前向传播一次得到结果
比如猫狗分类,传入猫的图片
已经有的模型是有名的cifar数据集训练出来的

import numpy as np
import sys
# caffe_root = '/home/tyd/caffe/'  # this file should be run from {caffe_root}/examples (otherwise change this line)
# sys.path.insert(0, caffe_root + 'python')

import caffe

caffe.set_mode_cpu()
#设置模型结构路径,参数路径
model_def = r'C:\Users\Administrator.DESKTOP-KMH7HN6\Downloads\Compressed\caffer_data\caffe-windows\models\bvlc_reference_caffenet\deploy.prototxt'
model_weights = r'C:\Users\Administrator.DESKTOP-KMH7HN6\Downloads\li_test_net\my_face_detect\temp\bvlc_reference_caffenet.caffemodel'
#未必训练的多模型就优秀,多试一试训练出来的其他模型看看效果
net = caffe.Net(model_def,      # defines the structure of the model
                model_weights,  # contains the trained weights
                caffe.TEST)     # use test mode (e.g., don't perform dropout)
#训练的时候减均值归一化,测试时也需要减均值
#caffe的均值是几万张图片共同得出的,有普遍性
mu = np.load(r"C:\Users\Administrator.DESKTOP-KMH7HN6\Downloads\Compressed\caffer_data\caffe-windows\python\caffe\imagenet\ilsvrc_2012_mean.npy")
mu = mu.mean(1).mean(1)  # average over pixels to obtain the mean (BGR) pixel values
print ('mean-subtracted values:', zip('BGR', mu))
#变换图片,让图片符合网络的输入格式
# create transformer for the input called 'data'
transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape})
#移动维度使得顺序一致,h w c->b c h w
transformer.set_transpose('data', (2,0,1))  # move image channels to outermost dimension
#读入mean值
transformer.set_mean('data', mu)            # subtract the dataset-mean value in each channel
#对数据压缩
transformer.set_raw_scale('data', 255)      # rescale from [0, 1] to [0, 255]
#caffe要求数据格式BGR,rab->bgr
transformer.set_channel_swap('data', (2,1,0))  # swap channels from RGB to BGR
#自定义处理图片格式
net.blobs['data'].reshape(1,        # batch size
                          3,         # 3-channel (BGR) images
                          227, 227)  # image size is 227x227
#读进图片
image = caffe.io.load_image(r"C:\Users\Administrator.DESKTOP-KMH7HN6\Downloads\Compressed\caffer_data\caffe-windows\examples\images\cat.jpg")
transformed_image = transformer.preprocess('data', image)
#将数据传入数据层
# copy the image data into the memory allocated for the net
net.blobs['data'].data[...] = transformed_image

### perform classification  使用网络前向传播一次
output = net.forward()
#output得到了所有的概率值,取概率最大的
output_prob = output['prob'][0]  # the output probability vector for the first image in the batch

print ('predicted class is:', output_prob.argmax())

在这里插入图片描述
在这里插入图片描述
想知道类别281是什么吗?
流程已经清楚了,那么接下来就开始做人脸检测,标出人的眼睛鼻子等特征点

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2021-11-28 11:16:07  更:2021-11-28 11:20:09 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 3:40:40-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码