【发布时间】:2019-12-09 23:24:47
【问题描述】:
我对编码比较陌生,我很感激任何帮助,但对我要温柔。
我正在研究用于神经网络的 MNIST 数据库,因为我想将结果转移到另一个问题上。我正在尝试做的是通过将一组图像包含到要分类的图像中来操纵 MNIST 训练数据集。请允许我构建方法:
- 在训练神经网络时,MNIST 数据库会提供手写数字 (x_train) 及其标签/类别 (y_train) 的图像
- 但是,我不仅希望使用单个图像输入来训练神经网络,而且还希望为神经网络提供可选图像以供选择
- 所以如果我想让机器对数字“5”进行分类,我将输入数字“5”的图像和一组随机图像,这些图像应该具有随机数量:
-> 输入 = 图像分类“5” |要引用“1”、“4”、“5”的图像,下一个将是 图像分类“0” |图片要引用“0”、“9”、“3”、“5”、“6”等...
“要参考的图像”应始终包含“要分类的数字”,而不是“要分类的图像”。意思是“图像分类“5”的索引不应与“图像参考...“5”的索引相同
-
到目前为止,我设法选择了随机数字 (random_with_N_digits()) 的随机图像 (digit_randomizer())。我想念的是:
- 排除自身的索引:要分类的索引“5”不是可供选择的索引“5”
- 要引用的图像不应有重复的数字
To 1.: 下面你可以看到我的函数 digit_randomizer()。我目前不知道如何解决这个问题,但使用嵌套循环检查“np.where(j != i)”
To 2.:我正在考虑将 y_train 分成 10 组不同的标签(每组代表一位)。但是我不知道我应该写什么样的命令,因为我需要定义随机数量的图像。从 10 个集合中随机选择一个随机图像,同时注意索引。
到目前为止,这是我的代码:
import keras as k
import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Conv2D, Dropout, Flatten, MaxPooling2D
import matplotlib.pyplot as plt
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
print('')
print('x_train shape:', x_train.shape)
# Reshaping the array to 4-dims so that it can work with the Keras API
x_train = x_train.reshape(x_train.shape[0], 28, 28, 1)
x_test = x_test.reshape(x_test.shape[0], 28, 28, 1)
input_shape = (28, 28, 1)
# Making sure that the values are float so that we can get decimal points after division
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
# Normalizing the RGB codes by dividing it to the max RGB value.
x_train /= 255
x_test /= 255
print('x_train shape reshaped:', x_train.shape)
print('Number of images in x_train', x_train.shape[0])
print('Number of images in x_test', x_test.shape[0])
classes = set(y_train)
print('Number of classes =', len(classes),'\n')
print('Classes: \n', classes, '\n')
print('y_train shape:', y_train.shape)
print('y_test shape:', y_test.shape)
import random
import warnings
warnings.filterwarnings("ignore")
from random import randint
#select a random image from the training data
def digit_select():
for j in range(1):
j = np.random.choice(np.arange(0, len(y_train)), size = (1,))
digit = (x_train[j] * 255).reshape((28, 28)).astype("uint8")
imgplot = plt.imshow(digit)
plt.title(y_train[j])
imgplot.set_cmap('Greys')
plt.show()
# return between 1 or 10 images
def random_with_N_digits():
range_start = 0
range_end = 9
return randint(range_start, range_end)
# return 1 or 10 random images
def digit_randomizer():
for i in range(random_with_N_digits()):
i = np.random.choice(np.arange(0, len(y_train)), size = (1,))
image = (x_train[i] * 255).reshape((28, 28)).astype("uint8")
imgplot = plt.imshow(image)
imgplot.set_cmap('Greys')
plt.title(y_train[i])
plt.show()
应该以某种方式将 digit_select 从 digit_randomizer 中排除,并且 digit_randomizer 应该只从 y_train 中为每个类别选择一个图像。
非常感谢任何想法。
代码编辑:
def digit_label_randselect():
j = np.random.choice(np.arange(0, len(y_train)), size=(1,))
return int(y_train[j])
print('Randomly selected label:', digit_label_randselect())
Output: Randomly selected label: 4
def n_reference_digits(input_digit_label):
other_digits = list(np.unique(y_train)) #create list with all digits
other_digits.remove(input_digit_label) #remove the input digit label
sample = random.sample(other_digits, len(np.unique(y_train))-1) #Take a sample of size n of the digits
sample.append(input_digit_label)
random.shuffle(sample)
return sample
print('Randomly shuffled labels:', n_reference_digits(digit_label_randselect()))
Output: Randomly shuffled labels: [8, 0, 6, 2, 7, 4, 3, 5, 9, 1]
'''returns a list of 10 random indices.
necessary to choose random 10 digits as a set, which will be used to train the NN.
the set needs to contain a single identical y_train value (label),
meaning that a random digit definitely has the same random digit in the set.
however their indices have to differ. moreover all y_train values (labels) have to be different,
meaning that the set contains a single representation of every digit.'''
def digit_indices_randselect():
listi = []
for i in range(10):
i = np.random.choice(np.arange(0, len(y_train)), size = (1,))
listi.append(i)
return listi
listindex = digit_indices_randselect()
print('Random list of indices:', listindex)
Output: Random list of indices: [array([53451]), array([31815]), array([4519]), array([21354]), array([14855]), array([45147]), array([42903]), array([37681]), array([1386]), array([9584])]
'''for every index in listindex return the corresponding index, pixel array and label'''
#TO DO: One Hot Encode the labels
def array_and_label_for_digit_indices_randselect():
listi = []
digit_data = []
labels = []
for i in listindex:
digit_array = x_train[i] #digit data (image array) is the data from index i
label = y_train[i] #corresponding label
listi.append(i)
digit_data.append(digit_array)
labels.append(label)
list3 = list(zip(listi, digit_data, labels))
return list3
array_and_label_for_digit_indices_randselect()
Output:[(array([5437]),
array([[[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 4, 29, 29, 29,
29, 29, 29, 29, 92, 91, 141, 241, 255, 228, 94, 0,
0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 45, 107, 179, 252, 252, 252,
253, 252, 252, 252, 253, 252, 252, 252, 253, 252, 224, 19,
0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 45, 240, 252, 253, 252, 252, 252,
253, 252, 252, 252, 253, 252, 252, 252, 253, 252, 186, 6,
0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 157, 252, 252, 253, 252, 252, 252,
253, 252, 252, 252, 241, 215, 252, 252, 253, 202, 19, 0,
0, 0, 0, 0],
[ 0, 0, 0, 0, 41, 253, 253, 253, 255, 234, 100, 0,
0, 0, 0, 0, 0, 70, 253, 253, 251, 125, 0, 0,
0, 0, 0, 0],
[ 0, 0, 0, 0, 66, 252, 252, 252, 253, 133, 0, 0,
0, 0, 0, 0, 0, 169, 252, 252, 200, 0, 0, 0,
0, 0, 0, 0],
[ 0, 0, 0, 0, 7, 130, 168, 168, 106, 19, 0, 0,
0, 0, 0, 0, 10, 197, 252, 252, 113, 0, 0, 0,
0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 128, 252, 252, 252, 63, 0, 0, 0,
0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 13, 204, 253, 253, 241, 0, 0, 0, 0,
0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 88, 253, 252, 233, 109, 0, 0, 0, 0,
0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 225, 253, 252, 234, 22, 0, 0, 0, 0,
0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 38, 237, 253, 252, 164, 15, 0, 0, 0, 0,
0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 26, 172, 253, 254, 228, 31, 0, 0, 0, 0, 0,
0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 114, 234, 252, 253, 139, 19, 0, 0, 0, 0, 0,
0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
111, 234, 252, 252, 94, 19, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
241, 252, 252, 202, 13, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76,
254, 253, 253, 78, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 225,
253, 252, 233, 22, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 225,
253, 233, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 187,
241, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0]]], dtype=uint8),
array([7], dtype=uint8)),...
'''for every index in x_train return a random index, its pixel array, label.
also return a list of 10 random indices (digit_indices_randselect())'''
def digit_with_set():
for i in x_train:
i = random.randrange(len(y_train)) #returns a random index of a digit between 0 - 60000
digit_data = x_train[i] #digit data (image array) is the data from index i
label = y_train[i] #corresponding label
#digit_randomizer() #returns a random set of 10 images
print("Index of digit to classify:", i), \
print("Digit to classify:", label), \
print("Corresponding array:", digit_data), \
print("Set of 10 Images:", array_and_label_for_digit_indices_randselect())
print("")
print("Next:")
digit_with_set()```
***PURPOSE Edit:*** The purpose of this approach is to research, whether a neural network can devise a model, which not only classifies the input, but also recognizes the possibility from choosing a label from the optional set. Meaning that the model not only classifies the "5" as the "5", but also looks into its options and finds a fit there as well.
This may not make much sense for an image classification problem. However I am working on a sequence to sequence problem in another project. The input sequences are in multiple columns in a .csv file. The output is another sequence. The issue lies within the very heterogenous input, so the accuracy is low and loss is very high.
This is how the data is structured:
**Input**: | AA_10| 31.05.2019 | CW20 | Project1 | **Output**: AA_Project1_[11]
**Input**: | | CW19 | | Project2 | **Output**: AA_Project2_[3]
**Input**: | y550 | 01.06.2019 | AA12 | Project1 | **Output**: AA_Project1_[12]
The AA_ProjectX_[Value] within the output is the main issue since its range varies from project to project. Project1 can have [0-12], Project 2 can have [0-20], ProjectX [0-N].
By adding a range of values to the input data I hope to restrict the network from learning values which are not part of the project.
Input: | AA_10| 31.05.2019 | CW20 | Project1 | [0,1,2,3,4,5,6,7,8,9,10,11,12] | Output: AA_Project1_[11]
So when I want to classify the digit 5, I give the machine a range of possibile classes and corresponding images to derive the output class from.
【问题讨论】:
标签: python image-processing random mnist digits