这是模型。这是一个基本的Tensorflow模型,它可以接收一个数字的图片并告诉你这是什么数字。* 我知道Python中的索引是从0开始的。我遇到的问题是这行代码“model.fit(np.array(test), np.array(num))”。请阅读下面的代码以获取更多信息。*
import kerasimport tensorflow as tfimport matplotlib.pyplot as pltimport numpy as npmnist = tf.keras.datasets.mnist(x_train, y_train),(x_test, y_test) = mnist.load_data()x_train = tf.keras.utils.normalize(x_train, axis=1)x_test = tf.keras.utils.normalize(x_test, axis=1)for train in range(len(x_train)): for row in range(28): for x in range(28): if x_train[train][row][x] != 0: x_train[train][row][x] = 1model = tf.keras.models.Sequential()model.add(tf.keras.layers.Flatten())model.add(tf.keras.layers.Dense(128, activation=tf.nn.relu))model.add(tf.keras.layers.Dense(128, activation=tf.nn.relu))model.add(tf.keras.layers.Dense(10, activation=tf.nn.softmax))model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])model.fit(x_train, y_train, epochs=5)model.save('epic_num_reader.model')print("Model saved")
在下面的代码中,函数“user_train”出现了错误。具体来说是这一行“model.fit(np.array(test), np.array(num))”。这段代码会弹出一个框,让你画一个数字,模型会在你按下空格键后尝试识别你画的是什么数字。我希望能够让用户画出数字,然后用这些数字来训练模型。
import sys, os, randomstdout = sys.__stdout__stderr = sys.__stderr__sys.stdout = open(os.devnull,'w')sys.stderr = open(os.devnull,'w')import pygameimport tensorflow as tfimport matplotlib.pyplot as pltimport numpy as npfrom tkinter import *from tkinter import messageboxsys.stdout = stdoutsys.stderr = stderrclass pixel(object):def __init__(self, x, y, width, height): self.x = x self.y = y self.width = width self.height = height self.color = (255,255,255) self.neighbors = []def draw(self, surface): pygame.draw.rect(surface, self.color, (self.x, self.y, self.x + self.width, self.y + self.height))def getNeighbors(self, g): # 获取网格中每个像素的邻居,用于绘制较粗的线条 j = self.x // 20 # 变量 i 负责表示网格中的当前列值 i = self.y // 20 # 变量 j 负责表示网格中的当前行值 rows = 28 cols = 28 # 水平和垂直邻居 if i < cols - 1: # 右侧 self.neighbors.append(g.pixels[i + 1][j]) if i > 0: # 左侧 self.neighbors.append(g.pixels[i - 1][j]) if j < rows - 1: # 上方 self.neighbors.append(g.pixels[i][j + 1]) if j > 0: # 下方 self.neighbors.append(g.pixels[i][j - 1]) # 对角线邻居 if j > 0 and i > 0: # 左上角 self.neighbors.append(g.pixels[i - 1][j - 1]) if j + 1 < rows and i > -1 and i - 1 > 0: # 左下角 self.neighbors.append(g.pixels[i - 1][j + 1]) if j - 1 < rows and i < cols - 1 and j - 1 > 0: # 右上角 self.neighbors.append(g.pixels[i + 1][j - 1]) if j < rows - 1 and i < cols - 1: # 右下角 self.neighbors.append(g.pixels[i + 1][j + 1])class grid(object):pixels = []def __init__(self, row, col, width, height): self.rows = row self.cols = col self.len = row * col self.width = width self.height = height self.generatePixels() passdef draw(self, surface): for row in self.pixels: for col in row: col.draw(surface)def generatePixels(self): x_gap = self.width // self.cols y_gap = self.height // self.rows self.pixels = [] for r in range(self.rows): self.pixels.append([]) for c in range(self.cols): self.pixels[r].append(pixel(x_gap * c, y_gap * r, x_gap, y_gap)) for r in range(self.rows): for c in range(self.cols): self.pixels[r][c].getNeighbors(self)def clicked(self, pos): #返回用户点击的网格位置 try: t = pos[0] w = pos[1] g1 = int(t) // self.pixels[0][0].width g1 = int(t) // self.pixels[0][0].width g2 = int(w) // self.pixels[0][0].height return self.pixels[g2][g1] except: passdef convert_binary(self): li = self.pixels newMatrix = [[] for x in range(len(li))] for i in range(len(li)): for j in range(len(li[i])): if li[i][j].color == (255,255,255): newMatrix[i].append(0) else: newMatrix[i].append(1) mnist = tf.keras.datasets.mnist (x_train, y_train), (x_test, y_test) = mnist.load_data() x_test = tf.keras.utils.normalize(x_test, axis=1) for row in range(28): for x in range(28): x_test[0][row][x] = newMatrix[row][x] return x_test[:1]def guess(li): model = tf.keras.models.load_model('epic_num_reader.model') predictions = model.predict(li) print(predictions[0]) t = (np.argmax(predictions[0])) print("我预测这个数字是:", t) window = Tk() window.withdraw() messagebox.showinfo("预测", "我预测这个数字是: " + str(t)) window.destroy() #plt.imshow(li[0], cmap=plt.cm.binary) #plt.show()############################### 出现错误的函数 ####def user_train(test, num): model = tf.keras.models.load_model('epic_num_reader.model') test = np.array(test) test = np.reshape(test, (28,28)) model.fit(np.array(test), np.array(num)) model.save('epic_num_reader.model')########################################################def main(): run = True while run: for event in pygame.event.get(): if event.type == pygame.QUIT: run = False if event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE: li = g.convert_binary() guess(li) g.generatePixels() elif event.key == pygame.K_0: test = g.convert_binary() user_train(test, 0) g.generatePixels() if pygame.mouse.get_pressed()[0]: pos = pygame.mouse.get_pos() clicked = g.clicked(pos) clicked.color = (0,0,0) for n in clicked.neighbors: n.color = (0,0,0) if pygame.mouse.get_pressed()[2]: try: pos = pygame.mouse.get_pos() clicked = g.clicked(pos) clicked.color = (255,255,255) except: pass g.draw(win) pygame.display.update()pygame.init()width = height = 560win = pygame.display.set_mode((width, height))pygame.display.set_caption("数字猜测")g = grid(28, 28, width, height)main()pygame.quit()quit()
这是完整的错误信息:
Traceback (most recent call last):File "D:/Users/user/AppData/Local/Programs/Pycharm/numbersML/drawNumber.py", line 184, in <module>main()File "D:/Users/user/AppData/Local/Programs/Pycharm/numbersML/drawNumber.py", line 157, in mainuser_train(test, 0)File "D:/Users/user/AppData/Local/Programs/Pycharm/numbersML/drawNumber.py", line 140, in user_trainmodel.fit(np.array(test), np.array(num))File "D:\Users\user\AppData\Local\Programs\Pycharm\numbersML\venv\lib\site-packages\tensorflow\python\keras\engine\training.py", line 718, in fituse_multiprocessing=use_multiprocessing)File "D:\Users\user\AppData\Local\Programs\Pycharm\numbersML\venv\lib\site-packages\tensorflow\python\keras\engine\training_v2.py", line 235, in fituse_multiprocessing=use_multiprocessing)File "D:\Users\user\AppData\Local\Programs\Pycharm\numbersML\venv\lib\site-packages\tensorflow\python\keras\engine\training_v2.py", line 582, in _process_training_inputsuse_multiprocessing=use_multiprocessing)File "D:\Users\user\AppData\Local\Programs\Pycharm\numbersML\venv\lib\site-packages\tensorflow\python\keras\engine\training_v2.py", line 635, in _process_inputsx, y, sample_weight=sample_weights)File "D:\Users\user\AppData\Local\Programs\Pycharm\numbersML\venv\lib\site-packages\tensorflow\python\keras\engine\training.py", line 2186, in _standardize_user_databatch_size=batch_size)File "D:\Users\user\AppData\Local\Programs\Pycharm\numbersML\venv\lib\site-packages\tensorflow\python\keras\engine\training.py", line 2281, in _standardize_tensorstraining_utils.check_array_lengths(x, y, sample_weights)File "D:\Users\user\AppData\Local\Programs\Pycharm\numbersML\venv\lib\site-packages\tensorflow\python\keras\engine\training_utils.py", line 730, in check_array_lengthsset_y = set_of_lengths(targets)File "D:\Users\user\AppData\Local\Programs\Pycharm\numbersML\venv\lib\site-packages\tensorflow\python\keras\engine\training_utils.py", line 725, in set_of_lengthsfor y in xFile "D:\Users\user\AppData\Local\Programs\Pycharm\numbersML\venv\lib\site-packages\tensorflow\python\keras\engine\training_utils.py", line 726, in <listcomp>if y is not None and not is_tensor_or_composite_tensor(y)IndexError: tuple index out of range
回答:
问题在于,’test’变量只是一个二维数组,而Tensorflow期望的是一个包含二维数组的数组。
原来是这样的:test = np.array(test) model.fit(np.array(test), np.array(num))
现在改成了这样:test = [test] num = [num] model.fit(np.array(test), np.array(num))