使用tensorflow搭建一個神經網路,實現一個分類問題
阿新 • • 發佈:2018-11-24
工欲善其事必先利其器,首先,我們來說說關於環境搭建的問題。
安裝的方法有一萬種,但是我還是推薦下面這種安裝方法,簡單方便,不會出現很多莫名其妙的問題。
Anaconda + Jupyter + tensorflow
安裝的具體流程見下面的視訊連結:
https://www.youtube.com/watch?v=G2GqLWOERjQ (需要科學上網)
資料集
資料集採用的比利時這個國家的交通標誌。從 https://btsd.ethz.ch/shareddata/ 可以獲得資料, BelgiumTSC_Training (171.3MBytes)和 BelgiumTSC_Testing (76.5MBytes)分別代表我們的訓練資料和測試資料。
資料集的說明
Trainging資料夾中有62個資料夾,每一個資料夾中若干張圖片,資料夾中圖片就是我們的屬性,標籤是資料夾的名字。
我們的訓練目標就是,給定一張圖片,判斷這張圖片屬於哪一個資料夾(分類問題)。
上乾貨,程式碼!
-載入資料,並建立訓練集的屬性和標籤
def load_data(data_dir): # Get all subdirectories of data_dir. Each represents a label. directories = [d for d in os.listdir(data_dir) if os.path.isdir(os.path.join(data_dir, d))] # print(directories) # Loop through the label directories and collect the data in # two lists, labels and images. labels = [] images = [] for d in directories: label_dir = os.path.join(data_dir, d) file_names = [os.path.join(label_dir, f) for f in os.listdir(label_dir) if f.endswith(".ppm")] for f in file_names: images.append(data.imread(f)) labels.append(int(d)) return images, labels ROOT_PATH = "E:/machineLearning/tensorflow/data/" #這裡需要根據自己資料存放的路徑進行修改 train_data_dir = os.path.join(ROOT_PATH, "BelgiumTSC_Training/Training") test_data_dir = os.path.join(ROOT_PATH, "BelgiumTSC_Testing/Testing") images, labels = load_data(train_data_dir)
images_array = np.array(images) labels_array = np.array(labels) # Print the `images` dimensions print(images_array.ndim) # Print the number of `images`'s elements print(images_array.size) # Print the first instance of `images` # print(images_array[0]) # Print the `labels` dimensions print(labels_array.ndim) # Print the number of `labels`'s elements print(labels_array.size) # Count the number of labels print(len(set(labels_array)))
-特徵抽取
縮放影象:
# Resize images
images32 = [transform.resize(image, (28, 28)) for image in images]
images32 = np.array(images32)
print(images32[0])
將彩色影象灰度化
for i in range(len(traffic_signs)):
plt.subplot(1, 4, i+1)
plt.axis('off')
plt.imshow(images32[traffic_signs[i]], cmap="gray")
plt.subplots_adjust(wspace=0.5)
plt.show()
print(images32.shape)
-使用Tensorflow訓練一個神經網路
import tensorflow as tf
x = tf.placeholder(dtype = tf.float32, shape = [None, 28, 28])
y = tf.placeholder(dtype = tf.int32, shape = [None])
images_flat = tf.contrib.layers.flatten(x)
logits = tf.contrib.layers.fully_connected(images_flat, 62, tf.nn.relu)
loss = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(labels = y, logits = logits))
train_op = tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss)
correct_pred = tf.argmax(logits, 1)
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
print("images_flat: ", images_flat)
print("logits: ", logits)
print("loss: ", loss)
print("predicted_labels: ", correct_pred)
執行神經網路
sess = tf.Session()
sess.run(tf.global_variables_initializer())
for i in range(201):
print('EPOCH', i)
_, accuracy_val = sess.run([train_op, accuracy], feed_dict={x: images32, y: labels})
if i % 10 == 0:
print("Loss: ", loss)
print('DONE WITH EPOCH')
執行神經網路
# Pick 10 random images
sample_indexes = random.sample(range(len(images32)), 10)
sample_images = [images32[i] for i in sample_indexes]
sample_labels = [labels[i] for i in sample_indexes]
# Run the "predicted_labels" op.
predicted = sess.run([correct_pred], feed_dict={x: sample_images})[0]
# Print the real and predicted labels
print(sample_labels)
print(predicted)
-展示預測結果
# Display the predictions and the ground truth visually.
fig = plt.figure(figsize=(10, 10))
for i in range(len(sample_images)):
truth = sample_labels[i]
prediction = predicted[i]
plt.subplot(5, 2,1+i)
plt.axis('off')
color='green' if truth == prediction else 'red'
plt.text(40, 10, "Truth: {0}\nPrediction: {1}".format(truth, prediction),
fontsize=12, color=color)
plt.imshow(sample_images[i])
plt.show()
-預測測試集
# Load the test data
test_images, test_labels = load_data(test_data_dir)
# Transform the images to 28 by 28 pixels
test_images28 = [transform.resize(image, (28, 28)) for image in test_images]
# Convert to grayscale
from skimage.color import rgb2gray
test_images28 = rgb2gray(np.array(test_images28))
# Run predictions against the full test set.
predicted = sess.run([correct_pred], feed_dict={x: test_images28})[0]
# Calculate correct matches
match_count = sum([int(y == y_) for y, y_ in zip(test_labels, predicted)])
# Calculate the accuracy
accuracy = match_count / len(test_labels)
# Print the accuracy
print("Accuracy: {:.3f}".format(accuracy))
-關閉session
sess.close()
預測的準確率大概是57.8%