我对深度学习和TensorFlow/Keras非常陌生,所以在尝试拟合一个模型来将图像分类为“狗”或“猫”时遇到了错误(图像数据库可以在这里找到:https://www.microsoft.com/en-us/download/details.aspx?id=54765)。模型是在一个单独的模块中编写、保存和打开的,因为我正在学习并遵循一个YouTube教程(https://www.youtube.com/watch?v=WvoLTXIjBYU)。第一段代码涉及创建和保存模型(使用pickle),第二段代码是训练实际卷积网络的部分。
图像数据库已被下载,保存到文件目录中,并编写了一个模型来训练分类器。代码如下:
import numpy as npimport matplotlib.pyplot as pltimport osimport cv2DATADIR = "Pictures\\kagglecatsanddogs_3367a\\PetImages" #Workspace directory changed for postingCATEGORIES = ["Dog", "Cat"]#Iterate between all photos of dogs and catsfor category in CATEGORIES: path = os.path.join(DATADIR, category) #path to cats or dogs dir for img in os.listdir(path): img_array = cv2.imread(os.path.join(path, img), cv2.IMREAD_GRAYSCALE) #Converts to grayscale, does not need color in this specific instance) plt.imshow(img_array, cmap = "gray") break break#Print image dimensionsprint(img_array.shape)#All the images are different-shaped photos, so they must be normalized#Everything must be made the same shape#Decide on the image size you want to go withIMG_SIZE = 180new_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE))training_data = []def create_training_data(): #With goal of iterating through everything and building the dataset for category in CATEGORIES: path = os.path.join(DATADIR, category) #path to cats or dogs dir class_num = CATEGORIES.index(category) for img in os.listdir(path): try: img_array = cv2.imread(os.path.join(path, img), cv2.IMREAD_GRAYSCALE) #Converts to grayscale, does not need color in this specific instance) new_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE)) training_data.append([new_array, class_num]) except Exception as e: passcreate_training_data()print(len(training_data))#Shuffle the dataimport randomrandom.shuffle(training_data)for sample in training_data[:10]: print(sample[1])#Packs data into variables we will usex = []y = []for features, label in training_data: x.append(features) y.append(label)x = np.array(x).reshape(-1, IMG_SIZE, IMG_SIZE, 1)#Model was saved with pickleimport picklepickle_out = open("x.pickle", "wb")pickle.dump(x, pickle_out)pickle_out.close()pickle_out = open("y.pickle", "wb")pickle.dump(y, pickle_out)pickle_out.close()
然后在另一个Jupyter Notebook文件中打开代码并用于构建CNN:
#Import necessary packagesimport tensorflow as tffrom tensorflow.keras.models import Sequentialfrom tensorflow.keras.layers import Dense, Dropout, Activation, Flatten, Conv2D, MaxPooling2Dimport pickle#Load models generated in previous tutorialx = pickle.load(open("x.pickle", "rb"))y = pickle.load(open("y.pickle", "rb"))#Normalize the data#255 is used due to RGB imageryx = x/255#Model building: First layermodel = Sequential()#Convolutional networkmodel.add(Conv2D(64, (3,3), input_shape = x.shape[1:]))model.add(Activation("relu"))#Poolingmodel.add(MaxPooling2D(pool_size = (2,2)))#Model building: Second layer#Convolutional networkmodel.add(Conv2D(64, (3,3), input_shape = x.shape[1:]))model.add(Activation("relu"))#Poolingmodel.add(MaxPooling2D(pool_size = (2,2)))#Final output layermodel.add(Flatten())model.add(Dense(64))model.add(Dense(1))model.add(Activation('sigmoid'))model.compile(loss= "binary_crossentropy", optimizer = "adam", metrics = ['accuracy'])model.fit(x, y, batch_size = 32, epochs = 3, validation_split = 0.1)
然后抛出异常:
---------------------------------------------------------------------------ValueError Traceback (most recent call last)<ipython-input-6-bb5f154147cd> in <module> 39 metrics = ['accuracy']) 40 ---> 41 model.fit(x, y, batch_size = 32, epochs = 3, validation_split = 0.1)~\AppData\Roaming\Python\Python36\site-packages\tensorflow\python\keras\engine\training.py in _method_wrapper(self, *args, **kwargs) 106 def _method_wrapper(self, *args, **kwargs): 107 if not self._in_multi_worker_mode(): # pylint: disable=protected-access--> 108 return method(self, *args, **kwargs) 109 110 # Running inside `run_distribute_coordinator` already.~\AppData\Roaming\Python\Python36\site-packages\tensorflow\python\keras\engine\training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, validation_batch_size, validation_freq, max_queue_size, workers, use_multiprocessing) 1038 (x, y, sample_weight), validation_data = ( 1039 data_adapter.train_validation_split(-> 1040 (x, y, sample_weight), validation_split=validation_split)) 1041 1042 if validation_data:~\AppData\Roaming\Python\Python36\site-packages\tensorflow\python\keras\engine\data_adapter.py in train_validation_split(arrays, validation_split) 1374 raise ValueError( 1375 "`validation_split` is only supported for Tensors or NumPy "-> 1376 "arrays, found following types in the input: {}".format(unsplitable)) 1377 1378 if all(t is None for t in flat_arrays):ValueError: `validation_split` is only supported for Tensors or NumPy arrays, found following types in the input: [<class 'int'>, <class 'int'>, <class 'int'>, <class 'int'>, <class 'int'>, <class 'int'>, <class 'int'>, <class 'int'>, <class 'int'>, <class 'int'>, <class 'int'>, <class 'int'>, <class 'int'>, <class 'int'>
如何解决这个错误?错误似乎出现在model.fit(x, y, batch_size = 32, epochs = 3, validation_split = 0.1)
这一行,因为当我运行不包含这一行的代码时,不会抛出任何异常。谢谢!
回答:
你应该对y的numpy数组也进行转换处理,而不仅仅是X。
X = []y = []for features,label in training_data: X.append(features) y.append(label)print(X[0].reshape(-1, IMG_SIZE, IMG_SIZE, 1))X = np.array(X).reshape(-1, IMG_SIZE, IMG_SIZE, 1)y = np.array(y)