上回制作了一个“至少可以运行”的东西,但有个小问题:mnist 在哪?或者,能自己找图片训练么?(虽说28×28且仅黑白通道的图不多见)


  ——自然是可以,也是应当的。并且我们可以想象,用于制作猫和喂猫的代码都不该有什么变化……其实饲料也不变,但是原料变了(从mnist变为自己的图集),所需的工具也跟着微调……


  我们回过去看看在制作饲料那一步,究竟做出了什么饲料——

  • X_train    (训练用图)

  • y_train    (训练图对应数字)

  • X_test     (测试用图)

  • y_test     (测试用数字)

  (num_classes 是由于代码设计不好,在下文只用了1次,而且是y_test的函数,完全可以去掉,用等号右边代替下文中的出现)


  你完全可以为了省事,直接把训练集当测试集,在喂猫的时候用相同的东西就可以了。总之【饲料有4个】。我为了简单,后两个就用前两个了……另外我根据他人代码,重新命了名,如下:

    (来源:csdn博客

  • data

  • label

  • data

  • label


  对于原料,自然可以把mnist那一行去掉了,但是又需要 os(系统库)和PIL(常用的图像库);os是python自带,PIL可以用 pip install pillow 安装(为何叫 pillow? ^_^),另外为了方便,把import numpy 改成 import numpy as np,np是numpy最普遍的别名了————你可以吧。然后这样制作饲料:(有python基础的人可能觉得我废话连篇……)

  (再另:自己找个mnist下载下来,一般是压缩包,解压后是图片文件夹。)

### 制作饲料
def load_data():
	path = "C:/Users/Administrator/Desktop/n/"    #放图片的文件夹
	name_lst = os.listdir(path)		# 获取路径下文件名列表
	lenth = len(name_lst)			# 获取文件数目
	
	data = np.empty((lenth,28,28,1),dtype="float32")	# 创建空数组 (data是4维数组,label是1维)
	label = np.empty((lenth,),dtype="uint8")

	for i in range(lenth):            # 把文件夹里的图填到数组里    
	                # 前提:28×28px 黑白图,且图片数字为n,则名称以“n.”开头,比如某张0的图片可命名为0.123.jpg
		s_name = name_lst[i]
		l_name = path + s_name
		img = PIL.Image.open(l_name)
		arr = np.asarray(img,dtype="float32")
		data[i,:,:,0] = arr/255
		n = int(s_name.split('.')[0])
		label[i] = n
		
	label = np_utils.to_categorical(label)    # (重整,之前版本也有这步)
	
	return data,label		
data, label = load_data()

X_train = data
y_train = label
X_test = data
y_test = label


  为了防止新手看不懂,这里把完整代码也放一下:

### 准备原料!
import numpy as np
import os, PIL

from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import Flatten
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import MaxPooling2D
from keras.utils import np_utils
# 其实完全可以不用seed,seed一般用于重现演示而已
        
        
### 制作饲料!
def load_data():
	path = "C:/Users/Administrator/Desktop/n/"
	name_lst = os.listdir(path)		# 获取路径下文件名列表
	lenth = len(name_lst)			# 获取文件数目
	
	data = np.empty((lenth,28,28,1),dtype="float32")	
	label = np.empty((lenth,),dtype="uint8")

	for i in range(lenth):
		s_name = name_lst[i]
		l_name = path + s_name
		img = PIL.Image.open(l_name)
		arr = np.asarray(img,dtype="float32")
		data[i,:,:,0] = arr/255
		n = int(s_name.split('.')[0])
		label[i] = n
		
	label = np_utils.to_categorical(label)
	
	return data,label		
data, label = load_data()

X_train = data
y_train = label
X_test = data
y_test = label

        
# 制作猫
def baseline_model():
 
    model = Sequential()
 
    model.add(Conv2D(32, (3, 3), padding='valid', input_shape=(28, 28,1), activation='relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))

 
    model.add(Conv2D(15, (3, 3), padding='valid' ,activation='relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))

 
    model.add(Flatten())


    model.add(Dense(128, activation='relu'))
    model.add(Dense(y_test.shape[1], activation='softmax'))

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

        
### 喂猫
 
model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=15, batch_size=128, verbose=2)


  如果你发现你的猫和别的教程里不一样,不要奇怪,猫自然是各种各样的……


  (2018-2-7 于地球)