关于使用keras进行图像识别的一些小错误(超新手)

实现将mnist数据集保存为图片文件

代码如下

import struct
from PIL import Image
import os
import numpy as np


# 参考文献  https://blog.csdn.net/u013066730/article/details/53769524
# 在此基础上做了修改


def save_image(filename, labels, save_dir, max_read):
    """
    读取mnist文件,以图片形式按照所属类别进行保存
    :param filename: mnist文件名
    :param labels:   图片对应的标签
    :param save_dir: 要保存的目录
    :param max_read: 最多读取多少图片
    """

    # 读入文件
    f = open(filename, 'rb')
    index = 0
    buf = f.read()
    f.close()
    # 读取图片总数
    magic, total, rows, columns = struct.unpack_from('>IIII', buf, index)
    index += struct.calcsize('>IIII')
    count = min(max_read, total)
    for i in range(count):
        # 读取一幅图片  28*28=784字节
        im = struct.unpack_from('>784B', buf, index)
        index += struct.calcsize('>784B')
        im = np.array(im, dtype='uint8')
        im = im.reshape(28, 28)
        # 调试时显示一下
        # fig=plt.figure()
        # plotwindow=fig.add_subplot(111)
        # plt.imshow(im,cmap='gray')
        # plt.show()
        # 保存到文件
        im = Image.fromarray(im)
        save_file = os.path.join(save_dir, str(labels[i]), '{:05d}.png'.format(i))
        im.save(save_file, 'png')
        print('save to ', save_file)


def read_label(filename, max_read):
    """
    读取标签
    :param filename: 标签文件名
    :param max_read: 最多读取数量
    :return: 读取的标签列表
    """
    # 打开文件并读入
    f = open(filename, 'rb')
    index = 0
    buf = f.read()
    f.close()
    # 读取总数量
    magic, total = struct.unpack_from('>II', buf, index)
    index += struct.calcsize('>II')
    count = min(max_read, total)
    labelArr = [0] * count
    # 依次读入标签,每个标签占一个字节
    for x in range(count):
        labelArr[x] = int(struct.unpack_from('>B', buf, index)[0])
        index += struct.calcsize('>B')
    return labelArr


def save_label(labels, save_dir):
    """
    保存标签
    :param labels: 标签列表
    :param save_dir: 保存目录
    :return: None
    """
    save = open(os.path.join(save_dir, 'label.txt'), 'w')
    save.write(','.join(map(lambda x: str(x), labels)))
    save.write('\n')
    save.close()
    print('save labels success')


def create_10_dir(parent):
    """
    创建0-910个目录(若已存在则不创建)
    :param parent:
    :return:
    """
    for i in range(10):
        dir = os.path.join(parent,str(i))
        if not os.path.isdir(dir):
            os.mkdir(dir)


if __name__ == '__main__':
    save_dir = 'e:\\smartcar\\tf\\train'
    create_10_dir(save_dir)
    max_read = 10000
    labels = read_label('E:\\smartcar\\t10k/train-labels.idx1-ubyte', max_read)
    save_label(labels, save_dir)
    save_image('E:\\smartcar\\t10k/train-images.idx3-ubyte', labels, save_dir, max_read)

    save_dir ='e:\\smartcar\\tf\\test'
    create_10_dir(save_dir)
    create_10_dir(savet_dir+'2')
    max_read = 100
    labels = read_label('E:\\smartcar\\t10k/t10k-labels.idx1-ubyte', max_read)
    save_label(labels, save_dir)
    save_image('E:\\smartcar\\t10k/t10k-images.idx3-ubyte', labels, save_dir, max_read)

可能出现的问题:
1.找不到文件,原因是没有下载相应文件在这里插入图片描述
解决办法:
进入http://yann.lecun.com/exdb/mnist/把出现的四个文件下载,使用时一定要添加到相应路径,如我下载到E:\smartcar\t10k下,使用时一定加上前缀。

2.路径无效,Windows系统下的文件路径是使用“\",Linux下使用”/“,但是这里不能使用E:\smartcar\t10k\train-labels.idx1-ubyte,如果这样使用会导致数据集无法保存到正确路径。

解决办法:
一定使用"/",可这样使用:E:\smartcar\t10k/train-labels.idx1-ubyte,也可以这样使用E:/smartcar/t10k/train-labels.idx1-ubyte

运行正确后如图:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

对指定目录下的图片实现分类训练

要注意,在放置图片时,图片所在的目录就是其所属类别
代码如下:

import sys
import os
from keras.preprocessing.image import ImageDataGenerator
from keras import optimizers
from keras.models import Sequential
from keras.layers import Dropout, Flatten, Dense, Activation
from keras.layers.convolutional import Convolution2D, MaxPooling2D
from keras import callbacks
import time


# 本文件训练分类模型

# 记录训练开始时间
start = time.time()

# 开发调试标志
DEV = True

if DEV:
  epochs = 10
else:
  epochs = 20

# 要训练的图片所在目录
train_data_path = 'e:\\smartcar\\tf\\train'
# 验证图片所在目录
validation_data_path = 'e:\\smartcar\\tf\\test'
"""
参数
"""
img_width, img_height = 150, 150
batch_size = 32
samples_per_epoch = 1000
validation_steps = 300
# 输出数量
nb_filters1 = 32
nb_filters2 = 64
# 卷积核大小
conv1_size = 3
conv2_size = 2
# 下采样
pool_size = 2
# 分类数
classes_num = 10
# 学习率
lr = 0.0004

# 创建模型
model = Sequential()
model.add(Convolution2D(nb_filters1, conv1_size, conv1_size, border_mode="same", input_shape=(img_width, img_height, 3)))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size=(pool_size, pool_size)))

model.add(Convolution2D(nb_filters2, conv2_size, conv2_size, border_mode="same"))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size=(pool_size, pool_size), dim_ordering='th'))

model.add(Flatten())
model.add(Dense(256))
model.add(Activation("relu"))
model.add(Dropout(0.5))
model.add(Dense(classes_num, activation='softmax'))

# 编译模型
model.compile(loss='categorical_crossentropy',
              optimizer=optimizers.RMSprop(lr=lr),
              metrics=['accuracy'])
# 图片数据生成
train_datagen = ImageDataGenerator(
    rescale=1. / 255,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True)
# 测试数据生成
test_datagen = ImageDataGenerator(rescale=1. / 255)

train_generator = train_datagen.flow_from_directory(
    train_data_path,
    target_size=(img_height, img_width),
    batch_size=batch_size,
    class_mode='categorical')

validation_generator = test_datagen.flow_from_directory(
    validation_data_path,
    target_size=(img_height, img_width),
    batch_size=batch_size,
    class_mode='categorical')

"""
Tensorboard 日志
"""
# log_dir = './tf-log/'
# tb_cb = callbacks.TensorBoard(log_dir=log_dir, histogram_freq=0)
# cbks = [tb_cb]

# 训练模型
model.fit_generator(
    train_generator,
    samples_per_epoch=samples_per_epoch,
    epochs=epochs,
    validation_data=validation_generator,
    # callbacks=cbks,
    validation_steps=validation_steps)

# 保存模型
target_dir = './models/'
if not os.path.exists(target_dir):
  os.mkdir(target_dir)
model.save('./models/model.h5')
model.save_weights('./models/weights.h5')

# 计算程序执行时间
end = time.time()
dur = end-start

if dur < 60:
    print("Execution Time:", dur, "seconds")
elif dur > 60 and dur < 3600:
    dur = dur/60
    print("Execution Time:", dur, "minutes")
else:
    dur = dur/(60*60)
    print("Execution Time:", dur, "hours")

可能出现问题:
1.Keras 安装的版本,使用pip安装即可,由于这里使用的是Anaconda,所以可以去其环境里查找未安装的版本,若出现版本不匹配问题,安装匹配版本即可

2.代码一般只会出现路径问题了多注意注意路径

注:
由于电脑不同,训练时间也不太相同,如果比较慢,多等等就好了。
如果出现此类警告,可以不用管它
在这里插入图片描述

对图片进行分类测试,并显示结果。

代码如下:

import os
import numpy as np
from keras.preprocessing.image import ImageDataGenerator, load_img, img_to_array
from keras.models import Sequential, load_model
import time
import cv2

# 测试图片分类

# 记录开始时间
start = time.time()

# 相关目录:模型路径,权重路径,测试路径
model_path = r'./models/model.h5'
model_weights_path = r'./models/weights.h5'
test_path = r'E:\smartcar\tf\test2'

# 加载训练好的模型
model = load_model(model_path)
model.load_weights(model_weights_path)

# 定义图片宽和高
img_width, img_height = 150, 150


def predict(file):
    """
    图片分类函数
    :param file: 要分类的图片
    :return: 分类结果
    """
    # 加载图片
    img = load_img(file, target_size=(img_width, img_height))
    x = img_to_array(img)
    x = np.expand_dims(x, axis=0)
    # 进行分类(预测)
    array = model.predict(x)
    result = array[0]
    print(result)
    answer = np.argmax(result)
    print('predicted: {}'.format(answer))
    return answer


# 创建用于显示结果的窗口
cv2.namedWindow("preview", cv2.WINDOW_NORMAL)
cv2.resizeWindow("preview", 200, 200)
# 对测试目录下的所有图片文件进行分类(预测)
for i, ret in enumerate(os.walk(test_path)):
    for i, filename in enumerate(ret[2]):
        if filename.startswith("."):
            continue
        # 得到完整图片文件名
        full_name = os.path.join(ret[0] , filename)
        print(full_name)
        # 进行分类
        result = predict(full_name)
        # 显示分类结果
        cv2.imshow("preview", cv2.imread(full_name))
        cv2.setWindowTitle("preview", str(result))
        cv2.waitKey(1000)

# 计算程序执行时间
end = time.time()
dur = end-start

if dur < 60:
    print("Execution Time:",dur,"seconds")
elif dur > 60 and dur<3600:
    dur=dur/60
    print("Execution Time:",dur,"minutes")
else:
    dur=dur/(60*60)
    print("Execution Time:",dur,"hours")

很多人在前两步不会有太大问题,到了这里测试可能不成功
这里出现的问题可能是:
1.测试路径中没有放测试图片

2.依旧是路径问题:
在这里插入图片描述
解决就看仔细了

3.一定要注意在路径前添加读写方式
在这里插入图片描述
如果这里不添加,那么整个测试会连最初的循环都进不去
一定要注意!

桃子找这个地方找了好久呜呜呜,老师给的例子并没有写出来,最开始我就以为是我的test_path错了导致循环进不去,经过百度,尝试多种做法,还是没法在os.walk(test_path)这里进入循环,后来终于发现了这个地方。
呜呜呜呜,搞了起码三小时,累了累了
总而言之
编程看命。

最终运行结果:
在这里插入图片描述
还有个小窗口(窗口名就是答案)在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值