• Platform OS: Linux Centos 7.6
  • Distribusi: Intel Xeon Gold 6152 (22x3,70 GHz);
  • Model GPU: NVIDIA Tesla V100 32 GB;
  • Jumlah node/CPU/Core/GPU: 26/52/1144/104;
  • TensorFlow diinstal dari (sumber atau biner): halaman web resmi
  • Versi TensorFlow (gunakan perintah di bawah): 2.1.0
  • Versi Python: 3.6.8

Deskripsi masalah:

Saat saya mengimplementasikan metode yang saya usulkan, menggunakan gaya implementasi kedua (lihat di bawah), saya menyadari bahwa kinerja algoritme memang aneh. Untuk lebih tepatnya, akurasi berkurang dan nilai kerugian meningkat sementara jumlah epoch meningkat.

Jadi saya mempersempit masalahnya dan akhirnya, saya memutuskan untuk memodifikasi beberapa kode dari halaman resmi TensorFlow untuk memeriksa apa yang terjadi. Seperti yang dijelaskan di halaman web resmi TF v2 ada dua gaya implementasi yang saya adopsi sebagai berikut.

Sebagai berikut:

import tensorflow as tf
from sklearn.preprocessing import OneHotEncoder
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
learning_rate = 1e-4
batch_size = 100
n_classes = 2
n_units = 80


# Generate synthetic data / load data sets
x_in, y_in = make_classification(n_samples=1000, n_features=10, n_informative=4, n_redundant=2, n_repeated=2, n_classes=2, n_clusters_per_class=2, weights=[0.5, 0.5], 
flip_y=0.01, class_sep=1.0, hypercube=True, shift=0.0, scale=1.0, shuffle=True, random_state=42)

x_in = x_in.astype('float32')
y_in = y_in.astype('float32').reshape(-1, 1)

one_hot_encoder = OneHotEncoder(sparse=False)
y_in = one_hot_encoder.fit_transform(y_in)
y_in = y_in.astype('float32')

x_train, x_test, y_train, y_test = train_test_split(x_in, y_in, test_size=0.4, random_state=42, shuffle=True)
x_test, x_val, y_test, y_val = train_test_split(x_test, y_test, test_size=0.5, random_state=42, shuffle=True)
print("shapes:", x_train.shape, y_train.shape, x_test.shape, y_test.shape, x_val.shape, y_val.shape)

V = x_train.shape[1]

model = tf.keras.models.Sequential([
        tf.keras.layers.Dense(n_units, activation='relu', input_shape=(V,)),
        tf.keras.layers.Dropout(0.2),
        tf.keras.layers.Dense(n_classes)
    ])

loss_fn = tf.keras.losses.BinaryCrossentropy(from_logits=True)

model.compile(optimizer='adam', loss=loss_fn, metrics=['accuracy'])

model.fit(x_train, y_train, epochs=5)

model.evaluate(x_test, y_test, verbose=2)

Output seperti yang diharapkan, seperti yang dapat dilihat di bawah ini:

600/600 [==============================] - 0s 419us/sample - loss: 0.7114 - accuracy: 0.5350
Epoch 2/5
600/600 [==============================] - 0s 42us/sample - loss: 0.6149 - accuracy: 0.6050
Epoch 3/5
600/600 [==============================] - 0s 39us/sample - loss: 0.5450 - accuracy: 0.6925
Epoch 4/5
600/600 [==============================] - 0s 46us/sample - loss: 0.4895 - accuracy: 0.7425
Epoch 5/5
600/600 [==============================] - 0s 40us/sample - loss: 0.4579 - accuracy: 0.7825

test: 200/200 - 0s - loss: 0.4110 - accuracy: 0.8350

Untuk lebih tepatnya, akurasi pelatihan meningkat dan nilai kerugian menurun seiring dengan meningkatnya jumlah epoch (yang diharapkan dan itu normal).

NAMUN, potongan kode berikut yang diadaptasi dari tautan di bawah ini:

Panduan memulai TensorFlow 2 untuk para ahli

Sebagai berikut:

import tensorflow as tf
from sklearn.preprocessing import OneHotEncoder
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split

learning_rate = 1e-4
batch_size = 100
n_classes = 2
n_units = 80

# Generate synthetic data / load data sets
x_in, y_in = make_classification(n_samples=1000, n_features=10, n_informative=4, n_redundant=2, n_repeated=2, n_classes=2, n_clusters_per_class=2, weights=[0.5, 0.5],flip_y=0.01, class_sep=1.0, hypercube=True, shift=0.0, scale=1.0, shuffle=True, random_state=42)

x_in = x_in.astype('float32')
y_in = y_in.astype('float32').reshape(-1, 1)

one_hot_encoder = OneHotEncoder(sparse=False)
y_in = one_hot_encoder.fit_transform(y_in)
y_in = y_in.astype('float32')

x_train, x_test, y_train, y_test = train_test_split(x_in, y_in, test_size=0.4, random_state=42, shuffle=True)
x_test, x_val, y_test, y_val = train_test_split(x_test, y_test, test_size=0.5, random_state=42, shuffle=True)

print("shapes:", x_train.shape, y_train.shape, x_test.shape, y_test.shape, x_val.shape, y_val.shape)

training_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train)).batch(batch_size)
valid_dataset = tf.data.Dataset.from_tensor_slices((x_val, y_val)).batch(batch_size)

testing_dataset = tf.data.Dataset.from_tensor_slices((x_test, y_test)).batch(batch_size)

V = x_train.shape[1]


class MyModel(tf.keras.models.Model):
        def __init__(self):
            super(MyModel, self).__init__()
            self.d1 = tf.keras.layers.Dense(n_units, activation='relu', input_shape=(V,))
            self.d2 = tf.keras.layers.Dropout(0.2)
            self.d3 = tf.keras.layers.Dense(n_classes,)

        def call(self, x):
            x = self.d1(x)
            x = self.d2(x)
            return self.d3(x)

# Create an instance of the model
model = MyModel()

loss_object = tf.keras.losses.BinaryCrossentropy(from_logits=True)

optimizer = tf.keras.optimizers.Adam()

train_loss = tf.keras.metrics.Mean(name='train_loss')
train_accuracy = tf.keras.metrics.BinaryCrossentropy(name='train_accuracy')

test_loss = tf.keras.metrics.Mean(name='test_loss')
test_accuracy = tf.keras.metrics.BinaryCrossentropy(name='test_accuracy')


@tf.function
def train_step(images, labels):
    with tf.GradientTape() as tape:
        # training=True is only needed if there are layers with different
        # behavior during training versus inference (e.g. Dropout).
        predictions = model(images,)  # training=True
        loss = loss_object(labels, predictions)
        gradients = tape.gradient(loss, model.trainable_variables)
        optimizer.apply_gradients(zip(gradients, model.trainable_variables))

        train_loss(loss)
        train_accuracy(labels, predictions)


@tf.function
def test_step(images, labels):
# training=False is only needed if there are layers with different
# behavior during training versus inference (e.g. Dropout).
predictions = model(images,)  # training=False
t_loss = loss_object(labels, predictions)

test_loss(t_loss)
test_accuracy(labels, predictions)


EPOCHS = 5

for epoch in range(EPOCHS):
# Reset the metrics at the start of the next epoch
    train_loss.reset_states()
    train_accuracy.reset_states()
    test_loss.reset_states()
    test_accuracy.reset_states()

for images, labels in training_dataset:
    train_step(images, labels)
    for test_images, test_labels in testing_dataset:
        test_step(test_images, test_labels)
   
   template = 'Epoch {}, Loss: {}, Accuracy: {}, Test Loss: {}, Test Accuracy: {}'
   print(template.format(epoch + 1,train_loss.result(), train_accuracy.result(),                           test_loss.result(), test_accuracy.result()))

Berperilaku memang aneh. Berikut adalah output dari potongan kode ini:

Epoch 1, Loss: 0.7299721837043762, Accuracy: 3.8341376781463623, Test Loss: 0.7290592193603516, Test Accuracy: 3.6925911903381348
Epoch 2, Loss: 0.6725851893424988, Accuracy: 3.1141700744628906, Test Loss: 0.6695905923843384, Test Accuracy: 3.2315549850463867
Epoch 3, Loss: 0.6256862878799438, Accuracy: 2.75959849357605, Test Loss: 0.6216427087783813, Test Accuracy: 2.920461416244507
Epoch 4, Loss: 0.5873140096664429, Accuracy: 2.4249706268310547, Test Loss: 0.5828182101249695, Test Accuracy: 2.575272560119629
Epoch 5, Loss: 0.555053174495697, Accuracy: 2.2128372192382812, Test Loss: 0.5501811504364014, Test Accuracy: 2.264410972595215

Seperti yang bisa dilihat, tidak hanya nilai akurasi yang aneh tetapi juga bukannya meningkat, begitu jumlah epoch meningkat, mereka berkurang?

Bisakah Anda menjelaskan apa yang terjadi di sini?

-1
sorooshi 7 Juli 2020, 21:27

1 menjawab

Jawaban Terbaik

Seperti yang ditunjukkan dalam komentar, saya membuat kesalahan dalam menggunakan metrik evaluasi. Saya seharusnya menggunakan BinaryAccuracy.

Selain itu, lebih baik untuk mengedit panggilan di versi lanjutan sebagai berikut:

def call(self, x, training=False):
    x = self.d1(x)
    if training:
        x = self.d2(x, training=training)
    return self.d3(x)
0
sorooshi 14 Juli 2020, 16:27