Accuracy of binary classification on MNIST “1” and “5” get better? - tensorflow

I tried the binary classification using MNIST only number “1” and “5”.
But the accuracy isn’t well.. The following program is anything wrong?
If you find something, please give me some advice.
loss: -9.9190e+04
accuracy: 0.5599
import tensorflow as tf
from tensorflow import keras
import numpy as np
import matplotlib.pyplot as plt
mnist = keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train = x_train / 255.0
x_test = x_test / 255.0
train_filter = np.where((y_train == 1) | (y_train == 5))
test_filter = np.where((y_test == 1) | (y_test == 5))
x_train, y_train = x_train[train_filter], y_train[train_filter]
x_test, y_test = x_test[test_filter], y_test[test_filter]
print("x_train", x_train.shape)
print("x_test", x_test.shape)
# x_train (12163, 28, 28)
# x_test (2027, 28, 28)
model = keras.Sequential(
[
keras.layers.Flatten(input_shape=(28, 28)),
keras.layers.Dense(128, activation="relu"),
keras.layers.Dense(1, activation="sigmoid"),
]
)
model.compile(optimizer="adam", loss="binary_crossentropy", metrics=["accuracy"])
model.fit(x_train, y_train, epochs=5)
loss, acc = model.evaluate(x_test, y_test, verbose=2)
print("accuracy:", acc)
# 2027/1 - 0s - loss: -9.9190e+04 - accuracy: 0.5599
# accuracy: 0.5599408

Your y_train and y_test is filled with class labels 1 and 5, but sigmoid activation in your last layer is squashing output between 0 and 1.
if you change 5 into 0 in your y you will get a really high accuracy:
y_train = np.where(y_train == 5, 0, y_train)
y_test = np.where(y_test == 5, 0, y_test)
result:
64/64 - 0s - loss: 0.0087 - accuracy: 0.9990

Related

Training CNN Model and accuracy stays at 1

I've been trying to train this CNN Model, It's a Tensorflow tutorial and I just changed the dataset ( I used fruit 360 dataset) without altering the core of the code. When it finishes training the accuracy stays constant at 0.8565 it doesn't change and when I try and test some images it almost always wrong.
What am I doing wrong?
Code output after executing
Here's the code I used
[enter image description here][1]import matplotlib.pyplot as plt
import numpy as np
import os
import PIL
import tensorflow as tf
import tarfile
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.models import Sequential
from tensorflow.keras import datasets, layers, models
from tensorflow import keras
import pathlib
dataset_url = "https://file.io/z5JM3sYAWXv4"
data_dir = tf.keras.utils.get_file(origin=dataset_url,
fname='tomatos',
untar=True,
extract=True)
data_dir = pathlib.Path(data_dir)
print(data_dir)
file_count = sum(len(files) for _, _, files in os.walk(r'tomatos'))
print(file_count)
batch_size = 32
img_height = 180
img_width = 180
train_ds = tf.keras.utils.image_dataset_from_directory(
data_dir,
validation_split=0.2,
subset="training",
seed=123,
image_size=(img_height, img_width),
batch_size=batch_size)
val_ds = tf.keras.utils.image_dataset_from_directory(
data_dir,
validation_split=0.2,
subset="validation",
seed=123,
image_size=(img_height, img_width),
batch_size=batch_size)
class_names = train_ds.class_names
print(class_names)
AUTOTUNE = tf.data.AUTOTUNE
train_ds = train_ds.cache().shuffle(1000).prefetch(buffer_size=AUTOTUNE)
val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)
num_classes = len(class_names)
model = Sequential([
layers.Rescaling(1./255, input_shape=(img_height, img_width, 3)),
layers.Conv2D(16, 3, padding='same', activation='relu'),
layers.MaxPooling2D(),
layers.Conv2D(32, 3, padding='same', activation='relu'),
layers.MaxPooling2D(),
layers.Conv2D(64, 3, padding='same', activation='relu'),
layers.MaxPooling2D(),
layers.Flatten(),
layers.Dense(128, activation='relu'),
layers.Dense(num_classes)
])
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
model.summary()
epochs=2
history = model.fit(
train_ds,
validation_data=val_ds,
epochs=epochs
)
data_augmentation = keras.Sequential(
[
layers.RandomFlip("horizontal",
input_shape=(img_height,
img_width,
3)),
layers.RandomRotation(0.1),
layers.RandomZoom(0.1),
]
)
model = Sequential([
data_augmentation,
layers.Rescaling(1./255),
layers.Conv2D(16, 3, padding='same', activation='relu'),
layers.MaxPooling2D(),
layers.Conv2D(32, 3, padding='same', activation='relu'),
layers.MaxPooling2D(),
layers.Conv2D(64, 3, padding='same', activation='relu'),
layers.MaxPooling2D(),
layers.Dropout(0.2),
layers.Flatten(),
layers.Dense(128, activation='relu'),
layers.Dense(num_classes)
])
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
model.summary()
epochs = 4
history = model.fit(
train_ds,
validation_data=val_ds,
epochs=epochs
)
sunflower_url = "https://puffycarrot.com/wp-content/uploads/2017/04/Green-tomatoes.jpg"
sunflower_path = tf.keras.utils.get_file('tomato2', origin=sunflower_url)
img = tf.keras.utils.load_img(
sunflower_path, target_size=(img_height, img_width)
)
img_array = tf.keras.utils.img_to_array(img)
img_array = tf.expand_dims(img_array, 0) # Create a batch
predictions = model.predict(img_array)
score = tf.nn.softmax(predictions[0])
print(
"This image most likely belongs to {} with a {:.2f} percent confidence."
.format(class_names[np.argmax(score)], 100 * np.max(score))
)
#Yaman Tarawneh, I tried replicating your above mentioned code in Google colab (using TF 2.8) and in Pycharm (using TF 2.7) and did not find the error.
Please check the output image for Pycharm :
and got the same output in Google colab :
Total params: 3,988,898
Trainable params: 3,988,898
Non-trainable params: 0
_________________________________________________________________
Epoch 1/4
78/78 [==============================] - 8s 41ms/step - loss: 0.0309 - accuracy: 0.9835 - val_loss: 5.6374e-07 - val_accuracy: 1.0000
Epoch 2/4
78/78 [==============================] - 2s 25ms/step - loss: 5.7533e-07 - accuracy: 1.0000 - val_loss: 2.7360e-07 - val_accuracy: 1.0000
Epoch 3/4
78/78 [==============================] - 2s 25ms/step - loss: 3.0400e-07 - accuracy: 1.0000 - val_loss: 1.3978e-07 - val_accuracy: 1.0000
Epoch 4/4
78/78 [==============================] - 2s 25ms/step - loss: 1.7403e-07 - accuracy: 1.0000 - val_loss: 7.2102e-08 - val_accuracy: 1.0000
This image most likely belongs to Tomato not Ripened with a 100.00 percent confidence.
For further analysis if the issue still persists, Please let us know which Python and Tensorflow version are you using.

Model.fit() output in Tensorflow 2

I am trying to use TF 2.0 for MNIST dataset with batch size of 128.
During learning I get the following message in an EPOCH. If my batch size is 128, what does 375 signify?
Epoch 13/200
375/375 [==============================] - 2s 4ms/step - loss: 0.2351 - accuracy: 0.9330 - val_loss: 0.2258 - val_accuracy: 0.9370
import tensorflow as tf
import numpy as np
from tensorflow import keras
# Network and training parameters.
EPOCHS = 200
BATCH_SIZE = 128
VERBOSE = 1
NB_CLASSES = 10 # number of outputs = number of digits
N_HIDDEN = 128
VALIDATION_SPLIT = 0.2 # how much TRAIN is reserved for VALIDATION
# Loading MNIST dataset.
# verify
# You can verify that the split between train and test is 60,000, and 10,000 respectively.
# Labels have one-hot representation.is automatically applied
mnist = keras.datasets.mnist
(X_train, Y_train), (X_test, Y_test) = mnist.load_data()
# X_train is 60000 rows of 28x28 values; we --> reshape it to
# 60000 x 784.
RESHAPED = 784
#
X_train = X_train.reshape(60000, RESHAPED)
X_test = X_test.reshape(10000, RESHAPED)
X_train = X_train.astype('float32')
X_test = X_test.astype('float32')
# Normalize inputs to be within in [0, 1].
X_train /= 255
X_test /= 255
print(X_train.shape[0], 'train samples')
print(X_test.shape[0], 'test samples')
# One-hot representation of the labels.
Y_train = tf.keras.utils.to_categorical(Y_train, NB_CLASSES)
Y_test = tf.keras.utils.to_categorical(Y_test, NB_CLASSES)
model = tf.keras.models.Sequential()
model.add(keras.layers.Dense(N_HIDDEN,
input_shape=(RESHAPED,),
name='dense_layer', activation='relu'))
model.add(keras.layers.Dense(N_HIDDEN,
name='dense_layer_2', activation='relu'))
model.add(keras.layers.Dense(NB_CLASSES,
name='dense_layer_3', activation='softmax'))
# Compiling the model.
model.compile(optimizer='SGD',
loss='categorical_crossentropy',
metrics=['accuracy'])
# Training the model.
model.fit(X_train, Y_train,
batch_size=BATCH_SIZE, epochs=EPOCHS,
verbose=VERBOSE, validation_split=VALIDATION_SPLIT)
The 375 is the number of steps per epoch your model must complete in order to finish one epoch. (Every epoch your model will process steps_per_epoch number of batches)
steps_per_epoch = len(X_train) // batch_size
but for your case, since you have specified 0.20 value to the validation_split parameter to model.fit()
steps_per_epoch = (len(X_train)*(1-VALIDATION_SPLIT)) // batch_size
so plugging the values,
steps = ((60,000) * (1-0.20)) // 128 = 375

how often are update_state() and call() method called and what are the dimension of the parameters in tf.keras?

I would like to know
(1) how often the call() method of tf.keras.losses.Loss
and the update_state() method of tf.keras.metrics.Metric gets called during a training:
are they called per each instance (observation)?
or called per each batch?
(2) the dimension of y_true and y_pred passed to those methods:
are their dimension (batch_size x output_dimension)
or (1 x output_dimension)
The following code snippet comes from
https://www.tensorflow.org/guide/keras/train_and_evaluate
For experiment I insert print(y_true.shape, y_pred.shape) in update_state() and I find that it is only printed once in the first epoch. From the print, it looks like y_true and y_pred have the dimension of
(1 x output_dimension) in this particular example but is it always the case?
So, additionally
(3) I would like to know why it is printed only once and only in the first epoch.
(4) I can't print the value of y_true or y_pred. How can I?
Epoch 1/3
(None, 1) (None, 10)
(None, 1) (None, 10)
782/782 [==============================] - 3s 4ms/step - loss: 0.5666 - categorical_true_positives: 22080.8940
Epoch 2/3
782/782 [==============================] - 3s 4ms/step - loss: 0.1680 - categorical_true_positives: 23877.1162
Epoch 3/3
782/782 [==============================] - 3s 4ms/step - loss: 0.1190 - categorical_true_positives: 24198.2733
<tensorflow.python.keras.callbacks.History at 0x1fb132cde80>
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
# Preprocess the data (these are NumPy arrays)
x_train = x_train.reshape(60000, 784).astype("float32") / 255
x_test = x_test.reshape(10000, 784).astype("float32") / 255
y_train = y_train.astype("float32")
y_test = y_test.astype("float32")
# Reserve 10,000 samples for validation
x_val = x_train[-10000:]
y_val = y_train[-10000:]
x_train = x_train[:-10000]
y_train = y_train[:-10000]
inputs = keras.Input(shape=(784,), name="digits")
x = layers.Dense(64, activation="relu", name="dense_1")(inputs)
x = layers.Dense(64, activation="relu", name="dense_2")(x)
outputs = layers.Dense(10, activation="softmax", name="predictions")(x)
model = keras.Model(inputs=inputs, outputs=outputs)
class CategoricalTruePositives(keras.metrics.Metric):
def __init__(self, name="categorical_true_positives", **kwargs):
super(CategoricalTruePositives, self).__init__(name=name, **kwargs)
self.true_positives = self.add_weight(name="ctp", initializer="zeros")
def update_state(self, y_true, y_pred, sample_weight=None):
print(y_true.shape, y_pred.shape) # For experiment
y_pred = tf.reshape(tf.argmax(y_pred, axis=1), shape=(-1, 1))
values = tf.cast(y_true, "int32") == tf.cast(y_pred, "int32")
values = tf.cast(values, "float32")
if sample_weight is not None:
sample_weight = tf.cast(sample_weight, "float32")
values = tf.multiply(values, sample_weight)
self.true_positives.assign_add(tf.reduce_sum(values))
def result(self):
return self.true_positives
def reset_states(self):
# The state of the metric will be reset at the start of each epoch.
self.true_positives.assign(0.0)
model.compile(
optimizer=keras.optimizers.RMSprop(learning_rate=1e-3),
loss=keras.losses.SparseCategoricalCrossentropy(),
metrics=[CategoricalTruePositives()],
)
model.fit(x_train, y_train, batch_size=64, epochs=3)
(1) how often the call() method of tf.keras.losses.Loss and the update_state() method of tf.keras.metrics.Metric gets called during a training:
The call method of tf.keras.losses.Loss and the update_state() are used at the end of each batch.
(2) the dimension of y_true and y_pred passed to those methods:
The dimensions of y_true is same as what you pass in y_train. The only change is, the first dimension of y_train will be no_of samples and in the case of y_true it will be batch_size. In your case it is (64, 1) where 64 is batch_size.
The dimensions of y_pred is the shape of output of the model. In your case it is (64, 10) because you have 10 dense units in final layer.
(3) I would like to know why it is printed only once and only in the first epoch.
The print statement is executed only once because tensorflow is executed in graph mode. Print will only work in eager mode. Add run_eagerly = True in model.compile step if you want to execute tensorflow code in eager mode.
(4) I can't print the value of y_true or y_pred. How can I?
Run the code in eager mode.
Code:
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
# Preprocess the data (these are NumPy arrays)
x_train = x_train.reshape(60000, 784).astype("float32") / 255
x_test = x_test.reshape(10000, 784).astype("float32") / 255
y_train = y_train.astype("float32")
y_test = y_test.astype("float32")
# Reserve 10,000 samples for validation
x_val = x_train[-10000:]
y_val = y_train[-10000:]
x_train = x_train[:-10000]
y_train = y_train[:-10000]
inputs = keras.Input(shape=(784,), name="digits")
x = layers.Dense(64, activation="relu", name="dense_1")(inputs)
x = layers.Dense(64, activation="relu", name="dense_2")(x)
outputs = layers.Dense(10, activation="softmax", name="predictions")(x)
model = keras.Model(inputs=inputs, outputs=outputs)
class CategoricalTruePositives(keras.metrics.Metric):
def __init__(self, name="categorical_true_positives", **kwargs):
super(CategoricalTruePositives, self).__init__(name=name, **kwargs)
self.true_positives = self.add_weight(name="ctp", initializer="zeros")
def update_state(self, y_true, y_pred, sample_weight=None):
print('update_state', y_true.shape, y_pred.shape) # For experiment
y_pred = tf.reshape(tf.argmax(y_pred, axis=1), shape=(-1, 1))
values = tf.cast(y_true, "int32") == tf.cast(y_pred, "int32")
values = tf.cast(values, "float32")
if sample_weight is not None:
sample_weight = tf.cast(sample_weight, "float32")
values = tf.multiply(values, sample_weight)
self.true_positives.assign_add(tf.reduce_sum(values))
def result(self):
return self.true_positives
def reset_states(self):
# The state of the metric will be reset at the start of each epoch.
self.true_positives.assign(0.0)
class CustomCallback(tf.keras.callbacks.Callback):
def on_epoch_begin(self, epoch, logs=None):
print("Start epoch {} of training".format(epoch))
def on_train_batch_begin(self, batch, logs=None):
keys = list(logs.keys())
print("...Training: start of batch {}".format(batch))
def on_train_batch_end(self, batch, logs=None):
print("...Training: end of batch {}".format(batch))
model.compile(
optimizer=keras.optimizers.RMSprop(learning_rate=1e-3),
loss=keras.losses.SparseCategoricalCrossentropy(),
metrics=[CategoricalTruePositives()],
run_eagerly = True,
)
model.fit(x_train, y_train, batch_size=64, epochs=3, verbose = 0, callbacks=[CustomCallback()])
Output:
Start epoch 0 of training
...Training: start of batch 0
update_state (64, 1) (64, 10)
...Training: end of batch 0
...Training: start of batch 1
update_state (64, 1) (64, 10)
...Training: end of batch 1
...Training: start of batch 2
update_state (64, 1) (64, 10)
...Training: end of batch 2
...Training: start of batch 3
update_state (64, 1) (64, 10)
...Training: end of batch 3
...Training: start of batch 4
update_state (64, 1) (64, 10)
...Training: end of batch 4
...Training: start of batch 5
update_state (64, 1) (64, 10)
...Training: end of batch 5
The above example will make the answer to your clear.

Keras custom loss function print tensor values

I try to implement object detector like yolo. It uses complex custom loss function. So I need to print/debug its tensors. I understand, that python code only builds computing graph so standard print won't work in not eager mode.
tensorflow 1.12.0
keras 2.2.4
I tried all methods from these posts Keras custom loss function not printing value of tensor, Debugging keras tensor values and nothing works. I tried tf.Print, tf.print, callback, K.tensor_print - the same result. In console i see only standart output messages. I`m not even sure if loss function been called. The answer from this post Keras - printing intermediate tensors in loss function (tf.Print and K.print_tensor do not work...) says that loss function sometimes doesn't even called! Ok, but how to use tf.contrib.eager.defun decorator then? The example is for pure tensorflow and dont't understand how to use it in keras.
import tensorflow as tf
from keras.datasets import fashion_mnist
import matplotlib.pyplot as plt
from keras.layers.convolutional import Conv2D, MaxPooling2D
from keras.layers import Flatten, Dense, Dropout
from keras.models import Sequential
from keras import optimizers
import numpy as np
from random import randrange
from keras.callbacks import LambdaCallback
import keras.backend as K
import keras
print(tf.__version__)
print(keras.__version__)
num_filters = 64
(x_train, y_train), (x_test, y_test) = fashion_mnist.load_data()
x_train = x_train.astype('float32') / 255
x_test = x_test.astype('float32') / 255
#reshape
x_train = x_train.reshape(60000,28,28,1)[:1000,...]
x_test = x_test.reshape(10000,28,28,1)[:100,...]
# One-hot encode the labels
y_train = tf.keras.utils.to_categorical(y_train, 10)[:1000,...]
y_test = tf.keras.utils.to_categorical(y_test, 10)[:100,]
labels = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
model = Sequential()
model.add(Conv2D(input_shape=(28,28,1), filters=num_filters,kernel_size=3,strides=(1, 1),padding="valid", activation='relu', use_bias=True))
model.add(MaxPooling2D(pool_size=2))
model.add(Dropout(0.3))
model.add(Conv2D(filters=num_filters,kernel_size=3,strides=(1, 1),padding="valid", activation='relu', use_bias=True))
model.add(MaxPooling2D(pool_size=2))
model.add(Dropout(0.3))
model.add(Flatten())
model.add(Dense(256, activation = 'relu'))
model.add(Dropout(0.5))
model.add(Dense(10, activation = 'softmax'))
#model.summary()
#loss 1
def customLoss(yTrue,yPred):
d = yPred-yTrue
d = K.print_tensor(d)
return K.mean(K.square(d), axis=-1)
#loss 2
def cat_loss(y_true, y_pred):
d = y_true - y_pred
d = tf.Print(d, [d], "Inside loss function")
return tf.reduce_mean(tf.square(d))
model.compile(loss=customLoss,
optimizer='adam')
import keras.callbacks as cbks
# 3 try to print with callback
class CustomMetrics(cbks.Callback):
def on_epoch_end(self, epoch, logs=None):
for k in logs:
if k.endswith('cat_loss'):
print(logs[k])
#checkpointer = ModelCheckpoint(filepath='model.weights.best.hdf5', verbose = 1, save_best_only=True)
model.fit(x_train,
y_train,
#verbose=1,
batch_size=16,
epochs=10,
validation_data=(x_test, y_test),
callbacks=[CustomMetrics()])
# Evaluate the model on test set
score = model.evaluate(x_test, y_test, verbose=0)
# Print test accuracy
print('\n', 'Test accuracy:', score)
rand_img = randrange(100)
result = np.argmax(model.predict(x_test[rand_img].reshape(1,28,28,1)))
plt.imshow(x_test[rand_img].reshape(28,28), cmap='gray')
plt.title(labels[result])
==========>......] - ETA: 0s - loss: 0.0243
832/1000 [=======================>......] - ETA: 0s - loss: 0.0242
Warning (from warnings module):
File "C:\Python36\lib\site-packages\keras\callbacks.py", line 122
% delta_t_median)
UserWarning: Method on_batch_end() is slow compared to the batch update (0.101474). Check your callbacks.
976/1000 [============================>.] - ETA: 0s - loss: 0.0238
992/1000 [============================>.] - ETA: 0s - loss: 0.0236
1000/1000 [==============================] - 3s 3ms/step - loss: 0.0239 - val_loss: 0.0352
Test accuracy: 0.035189545452594756```
The truth was somewhere near. Idle doesn't output tf.Print and therefore K.print_tensor() to it's shell, so when i used cmd.exe python train.py, i saw tensor output.

How can I reduce the loss rate of G and D in GAN?

I'm building a GAN using Tensorflow.
At first, I created a GAN that produces a 32x32 image.
Modified the model to add a layer to create a 128x128 image.
By the way, 32x32 GAN G, D loss value was ok, but the loss value is very high as the layer size and image size are increased.
I modified the layer and modified other hyper parameters to lower the loss, but it's still high.
I wonder how to reduce the loss of G and D.
import os.path
import numpy as np
from keras.models import *
from keras.layers import *
from keras.optimizers import *
from keras.layers.convolutional import Conv2DTranspose, MaxPooling2D, UpSampling2D, Conv2D
from keras.layers.core import Reshape, Dense, Dropout, Flatten
from keras.layers.advanced_activations import LeakyReLU, ReLU
from keras.layers.normalization import BatchNormalization
import keras.backend as K
import matplotlib.pyplot as plt
from PIL import Image
from keras.models import load_model
K.set_image_data_format('channels_last')
class Gan:
def __init__(self,img_data):
img_size = img_data.shape[1]
channel = img_data.shape[3] if len(img_data.shape) >= 4 else 1
self.img_data = img_data
self.input_shape = (img_size,img_size,channel)
self.img_rows = img_size
self.img_cols = img_size
self.channel = channel
self.noise_size = 128
self.create_d()
self.create_g()
optimizer = Adam(lr=0.0008)
self.D.compile(loss='binary_crossentropy', optimizer=optimizer)
optimizer = Adam(lr=0.0004)
self.D.trainable = False
self.AM = Sequential()
self.AM.add(self.G)
self.AM.add(self.D)
self.AM.compile(loss='binary_crossentropy',optimizer=optimizer)
def create_g(self):
self.G = Sequential()
dropout = 0.4
self.G.add(Dense(8 * 8 * 1024, input_dim=self.noise_size))
self.D.add(Dropout(dropout))
self.G.add(Activation('relu'))
self.G.add(Reshape((8, 8, 1024)))
self.G.add(Dropout(dropout))
self.G.add(Conv2DTranspose(512, 5, strides=2, padding ='same'))
self.D.add(Dropout(dropout))
self.G.add(Activation('relu'))
self.G.add(Conv2DTranspose(256, 5, strides=2, padding ='same'))
self.D.add(Dropout(dropout))
self.G.add(Activation('relu'))
self.G.add(Conv2DTranspose(128, 5, strides=2, padding ='same'))
self.D.add(Dropout(dropout))
self.G.add(Activation('relu'))
self.G.add(Conv2DTranspose(64, 5, strides=2, padding='same'))
self.D.add(Dropout(dropout))
self.G.add(Activation('relu'))
self.G.add(Conv2DTranspose(self.channel, 5, strides =1,padding='same'))
self.G.add(Activation('sigmoid'))
self.G.summary()
return self.G
def create_d(self):
self.D = Sequential()
dropout = 0.4
self.D.add(Conv2D(64, 5, strides=2, input_shape=self.input_shape, padding='same'))
self.D.add(LeakyReLU(alpha=0.2))
self.D.add(Dropout(dropout))
self.D.add(BatchNormalization(momentum=0.9))
self.D.add(Conv2D(128, 5, strides=2, input_shape=self.input_shape, padding='same'))
self.D.add(LeakyReLU(alpha=0.2))
self.D.add(Dropout(dropout))
self.D.add(Conv2D(256, 5, strides=2, input_shape=self.input_shape, padding='same'))
self.D.add(LeakyReLU(alpha=0.2))
self.D.add(Dropout(dropout))
self.D.add(Conv2D(512, 5, strides=1, input_shape=self.input_shape, padding='same'))
self.D.add(LeakyReLU(alpha=0.2))
self.D.add(Dropout(dropout))
self.D.add(Conv2D(1024, 5, strides=2, input_shape=self.input_shape, padding='same'))
self.D.add(LeakyReLU(alpha=0.2))
self.D.add(Dropout(dropout))
self.D.add(Flatten())
self.D.add(Dense(1))
self.D.add(Activation('sigmoid'))
self.D.summary()
return self.D
def train(self, sess, batch_size=100):
images_train = self.img_data[np.random.randint(0, self.img_data.shape[0], size=batch_size), :, :, :] #shape[0] -> image data의 숫자
noise = np.random.uniform(-1.0,1.0, size=[batch_size,self.noise_size])
images_fake = self.G.predict(noise)
x = np.concatenate((images_train, images_fake))
y = np.ones([2*batch_size,1])
y[batch_size:,:] = 0
self.D.trainable = True
d_loss = self.D.train_on_batch(x,y)
y = np.ones([batch_size,1])
noise = np.random.uniform(-1.0,1.0,size=[batch_size,self.noise_size])
self.D.trainable = False
a_loss = self.AM.train_on_batch(noise,y)
return d_loss, a_loss, images_fake
def save_weigths(self):
self.G.save_weights('gan_g_weights')
self.D.save_weights('gan_d_weights')
def load(self):
if os.path.isfile('gan_g_weights'):
self.G.load_weights('gan_g_weights')
print("Load G from file")
if os.path.isfile('gan_d_weights'):
self.D.load_weights('gan_d_weights')
print("Load D from file")
class faceData():
def __init__(self):
img_data_list = []
images = os.listdir("data_rgb1")
for path in images:
img = Image.open("data_rgb1/" + path)
img_data_list.append([np.array(img).astype('float32')])
self.x_train = np.vstack(img_data_list) / 255.0
print(self.x_train.shape)
dataset = faceData()
x_train =dataset.x_train
gan = Gan(x_train)
gan.load()
sess = tf.Session()
saver = tf.train.Saver()
sess.run(tf.global_variables_initializer())
epochs = 1000
sample_size = 10
batch_size = 50
train_per_epoch = x_train.shape[0] // batch_size
for epoch in range(0,epochs):
total_d_loss = 0.0
total_a_loss = 0.0
imgs = None
for batch in range(0, train_per_epoch):
d_loss, a_loss, t_imgs = gan.train(batch_size)
total_d_loss += d_loss
total_a_loss += a_loss
if imgs is None:
imgs = t_imgs
total_d_loss /= train_per_epoch
total_a_loss /= train_per_epoch
print("Epoch: {}, D Loss: {}, AM loss: {} " .format(epoch, total_d_loss, total_a_loss))
fig, ax = plt.subplots(1, sample_size, figsize = (sample_size, 1))
if epoch == 999:
for i in range(0, sample_size):
ax[i].set_axis_off()
ax[i].imshow(imgs[i].reshape((gan.img_rows, gan.img_cols, gan.channel)), interpolation='nearest');
plt.savefig('result%d.png' % epoch)
saver.save(sess, os.path.join('save', 'model_{}'.format(epoch)))
plt.close('all')
gan.save_weigths()
Result:
Epoch: 0, D Loss: 8.065221479096389, AM loss: 14.922738138189171
Epoch: 1, D Loss: 8.052544213793604, AM loss: 14.836829509831928
Epoch: 2, D Loss: 8.02602034776949, AM loss: 14.889192866794954
Epoch: 3, D Loss: 8.05762272074743, AM loss: 14.88101108667209
Epoch: 4, D Loss: 8.045719083795692, AM loss: 14.863829361000642
Epoch: 5, D Loss: 8.052135099614333, AM loss: 14.872829325913173
Epoch: 6, D Loss: 8.026918762226396, AM loss: 14.900647337666623
Epoch: 7, D Loss: 8.091860083759133, AM loss: 14.836829485626994
Epoch: 8, D Loss: 8.05686701130746, AM loss: 14.935828973799188
Epoch: 9, D Loss: 8.038368832641448, AM loss: 14.832738677862332
Epoch: 10, D Loss: 8.06173144016169, AM loss: 14.904738174477204
Epoch: 11, D Loss: 8.032495556749064, AM loss: 14.926010857983893
.
.
.
Welcome to the beatiful world of training a GAN. It is not an easy task yet not impossible. I cannot tell what the problems are just by looking at the loss from the first 10 epochs.
I highly recommend you to take a look at this article. You are probably having trouble since the equilibrium must have been broken when you added more layers.
Some tips recommended in the article are:
Look at the gradients.
Perform a pretraining.
Do not use hard labels.
Some personal tips are: add batch normalization at the generator. Do not use dense layers in the generator.
Good luck, have fun and please! Post some of the images you are generating I am very curious!