tl; dr Хоча це набір даних про класифікацію зображень, це залишається дуже легким завданням, для якого можна легко знайти пряме відображення від вхідних даних до прогнозів.
Відповідь:
Це дуже цікаве запитання, і завдяки простоті логістичної регресії ви справді можете дізнатися відповідь.
Логістична регресія полягає в тому, щоб кожне зображення прийняло введення і помножило їх на ваги, щоб створити його передбачення. Цікавим є те, що завдяки прямому відображенню між входом і виходом (тобто відсутність прихованого шару) значення кожної ваги відповідає тому, скільки кожного з входів враховується при обчисленні ймовірності кожного класу. Тепер, взявши ваги для кожного класу і переставивши їх на (тобто роздільну здатність зображення), ми можемо сказати, які пікселі є найбільш важливими для обчислення кожного класу .78478428×28
Знову зауважте, що це ваги .
Тепер подивіться на вищезазначене зображення і зосередиться на перших двох цифрах (тобто нуль і одна). Сині ваги означають, що інтенсивність цього пікселя багато сприяє для цього класу, а червоні значення означають, що він робить негативний внесок.
А тепер уявіть, як людина намалює ? Він малює круглу форму, яка порожня між ними. Саме так набирали ваги. Насправді, якщо хтось намалює середину зображення, це вважається негативно нулем. Тож для розпізнавання нулів вам не потрібні деякі складні фільтри та функції високого рівня. Ви можете просто переглянути місця намальованих пікселів і судити відповідно до цього.0
Те саме для . Вона завжди має пряму вертикальну лінію в середині зображення. Все інше рахується негативно.1
Решта цифр трохи складніші, але з невеликими уявами ви можете бачити , , і . Решта чисел трохи складніше, саме це фактично обмежує логістичну регресію від досягнення високих 90-х.2378
Завдяки цьому ви бачите, що логістична регресія має дуже хороший шанс отримати багато зображень правильно, і тому вона набирає такі високі результати.
Код для відтворення вищевказаної фігури трохи датований, але ось ви йдете:
import tensorflow as tf
import matplotlib.pyplot as plt
from tensorflow.examples.tutorials.mnist import input_data
# Load MNIST:
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
# Create model
x = tf.placeholder(tf.float32, shape=(None, 784))
y = tf.placeholder(tf.float32, shape=(None, 10))
W = tf.Variable(tf.zeros((784,10)))
b = tf.Variable(tf.zeros((10)))
z = tf.matmul(x, W) + b
y_hat = tf.nn.softmax(z)
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y * tf.log(y_hat), reduction_indices=[1]))
optimizer = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy) #
correct_pred = tf.equal(tf.argmax(y_hat, 1), tf.argmax(y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
# Train model
batch_size = 64
with tf.Session() as sess:
loss_tr, acc_tr, loss_ts, acc_ts = [], [], [], []
sess.run(tf.global_variables_initializer())
for step in range(1, 1001):
x_batch, y_batch = mnist.train.next_batch(batch_size)
sess.run(optimizer, feed_dict={x: x_batch, y: y_batch})
l_tr, a_tr = sess.run([cross_entropy, accuracy], feed_dict={x: x_batch, y: y_batch})
l_ts, a_ts = sess.run([cross_entropy, accuracy], feed_dict={x: mnist.test.images, y: mnist.test.labels})
loss_tr.append(l_tr)
acc_tr.append(a_tr)
loss_ts.append(l_ts)
acc_ts.append(a_ts)
weights = sess.run(W)
print('Test Accuracy =', sess.run(accuracy, feed_dict={x: mnist.test.images, y: mnist.test.labels}))
# Plotting:
for i in range(10):
plt.subplot(2, 5, i+1)
weight = weights[:,i].reshape([28,28])
plt.title(i)
plt.imshow(weight, cmap='RdBu') # as noted by @Eric Duminil, cmap='gray' makes the numbers stand out more
frame1 = plt.gca()
frame1.axes.get_xaxis().set_visible(False)
frame1.axes.get_yaxis().set_visible(False)