TensorFlow 2.0を使用してマルチクラスロジスティック回帰を構築しようとしています。正しいと思うコードを記述しましたが、良い結果が得られません。私の正確さは文字通り0.1%であり、損失でさえ減少していません。私は誰かがここで私を助けてくれることを望んでいました。
これは私がこれまで書いたコードです。私のモデルが機能するように改善する必要がある、ここで私が間違っていることを指摘してください。ありがとうございます!
from tensorflow.keras.datasets import fashion_mnist
from sklearn.model_selection import train_test_split
import tensorflow as tf
(x_train, y_train), (x_test, y_test) = fashion_mnist.load_data()
x_train, x_test = x_train/255., x_test/255.
x_train, x_val, y_train, y_val = train_test_split(x_train, y_train, test_size=0.15)
x_train = tf.reshape(x_train, shape=(-1, 784))
x_test = tf.reshape(x_test, shape=(-1, 784))
weights = tf.Variable(tf.random.normal(shape=(784, 10), dtype=tf.float64))
biases = tf.Variable(tf.random.normal(shape=(10,), dtype=tf.float64))
def logistic_regression(x):
lr = tf.add(tf.matmul(x, weights), biases)
return tf.nn.sigmoid(lr)
def cross_entropy(y_true, y_pred):
y_true = tf.one_hot(y_true, 10)
loss = tf.nn.softmax_cross_entropy_with_logits(labels=y_true, logits=y_pred)
return tf.reduce_mean(loss)
def accuracy(y_true, y_pred):
y_true = tf.cast(y_true, dtype=tf.int32)
preds = tf.cast(tf.argmax(y_pred, axis=1), dtype=tf.int32)
preds = tf.equal(y_true, preds)
return tf.reduce_mean(tf.cast(preds, dtype=tf.float32))
def grad(x, y):
with tf.GradientTape() as tape:
y_pred = logistic_regression(x)
loss_val = cross_entropy(y, y_pred)
return tape.gradient(loss_val, [weights, biases])
epochs = 1000
learning_rate = 0.01
batch_size = 128
dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
dataset = dataset.repeat().shuffle(x_train.shape[0]).batch(batch_size)
optimizer = tf.optimizers.SGD(learning_rate)
for Epoch, (batch_xs, batch_ys) in enumerate(dataset.take(epochs), 1):
gradients = grad(batch_xs, batch_ys)
optimizer.apply_gradients(Zip(gradients, [weights, biases]))
y_pred = logistic_regression(batch_xs)
loss = cross_entropy(batch_ys, y_pred)
acc = accuracy(batch_ys, y_pred)
print("step: %i, loss: %f, accuracy: %f" % (Epoch, loss, acc))
step: 1000, loss: 2.458979, accuracy: 0.101562
モデルが収束しておらず、問題は、シグモイドアクティベーションの直後に_tf.nn.softmax_cross_entropy_with_logits
_が続いていることです。 _tf.nn.softmax_cross_entropy_with_logits
_のドキュメントには次のように書かれています:
警告:このopは、効率化のために内部で
softmax
に対してlogits
を実行するため、スケールなしのロジットを想定しています。softmax
の出力でこの操作を呼び出さないでください。誤った結果が生成されます。
したがって、_tf.nn.softmax_cross_entropy_with_logits
_に渡す前に、前のレイヤーの出力でsoftmax、sigmoid、relu、tanh、またはその他のアクティブ化を実行しないでください。シグモイドまたはソフトマックス出力アクティベーションをいつ使用するかの詳細な説明については、 ここ を参照してください。
したがって、_return lr
_関数でreturn tf.nn.sigmoid(lr)
を_logistic_regression
_だけに置き換えると、モデルが収束します。
以下は、上記の修正を加えたコードの実際の例です。また、変数名epochs
を_n_batches
_に変更しました。これは、トレーニングループが実際には1000エポックではなく1000バッチを通過するためです(反復がさらに必要になる兆候があったため、最大で10000に増加しました)。
_from tensorflow.keras.datasets import fashion_mnist
from sklearn.model_selection import train_test_split
import tensorflow as tf
(x_train, y_train), (x_test, y_test) = fashion_mnist.load_data()
x_train, x_test = x_train/255., x_test/255.
x_train, x_val, y_train, y_val = train_test_split(x_train, y_train, test_size=0.15)
x_train = tf.reshape(x_train, shape=(-1, 784))
x_test = tf.reshape(x_test, shape=(-1, 784))
weights = tf.Variable(tf.random.normal(shape=(784, 10), dtype=tf.float64))
biases = tf.Variable(tf.random.normal(shape=(10,), dtype=tf.float64))
def logistic_regression(x):
lr = tf.add(tf.matmul(x, weights), biases)
#return tf.nn.sigmoid(lr)
return lr
def cross_entropy(y_true, y_pred):
y_true = tf.one_hot(y_true, 10)
loss = tf.nn.softmax_cross_entropy_with_logits(labels=y_true, logits=y_pred)
return tf.reduce_mean(loss)
def accuracy(y_true, y_pred):
y_true = tf.cast(y_true, dtype=tf.int32)
preds = tf.cast(tf.argmax(y_pred, axis=1), dtype=tf.int32)
preds = tf.equal(y_true, preds)
return tf.reduce_mean(tf.cast(preds, dtype=tf.float32))
def grad(x, y):
with tf.GradientTape() as tape:
y_pred = logistic_regression(x)
loss_val = cross_entropy(y, y_pred)
return tape.gradient(loss_val, [weights, biases])
n_batches = 10000
learning_rate = 0.01
batch_size = 128
dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
dataset = dataset.repeat().shuffle(x_train.shape[0]).batch(batch_size)
optimizer = tf.optimizers.SGD(learning_rate)
for batch_numb, (batch_xs, batch_ys) in enumerate(dataset.take(n_batches), 1):
gradients = grad(batch_xs, batch_ys)
optimizer.apply_gradients(Zip(gradients, [weights, biases]))
y_pred = logistic_regression(batch_xs)
loss = cross_entropy(batch_ys, y_pred)
acc = accuracy(batch_ys, y_pred)
print("Batch number: %i, loss: %f, accuracy: %f" % (batch_numb, loss, acc))
(removed printouts)
>> Batch number: 1000, loss: 2.868473, accuracy: 0.546875
(removed printouts)
>> Batch number: 10000, loss: 1.482554, accuracy: 0.718750
_