我在TensorFlow 2.0和Python 3.X中有一个用于二进制分类任务的神经网络,使用的是“心脏”数据集,该数据集可以从以下网址下载:
神经网络使用“ ReLU”激活功能和Adam梯度下降优化器具有两个隐藏层。我使用的自定义循环使用的是“ apply_gradients()”和“ GradientTape()”方法,而不是“ fit()”方法。
此外,原始的CSV文件使用“ pandas”(pd)读取,然后再使用API加载到TensorFlow中。
我的代码如下:
# Load CSV file-
data = pd.read_csv("heart.csv")
# Get shape/dimension of data-
data.shape
# (303, 14)
# Check for missing values-
data.isnull().values.any()
# False
# Convert 'thal' column which is an object in the dataframe to a discrete
# numerical value-
data['thal'] = pd.Categorical(data['thal'])
data['thal'] = data.thal.cat.codes
# Remove 'target' attribute-
target = data.pop('target')
# Load pandas DataFrame to TensorFlow-
dataset = tf.data.Dataset.from_tensor_slices((data.values, target.values))
# Shuffle and batch the dataset-
train_dataset = dataset.shuffle(buffer_size=len(data)).batch(batch_size=1, drop_remainder=False)
# Create a neural network:
model = tf.keras.Sequential([
tf.keras.layers.InputLayer(input_shape = (13,), dtype = tf.float64),
tf.keras.layers.Dense(10, activation = 'relu'),
tf.keras.layers.Dense(10, activation = 'relu'),
tf.keras.layers.Dense(1, activation = 'sigmoid')
])
def cost_fn(model, x, y):
'''
Cost function to compute binary cross-entropy
'''
y_ = model(x)
# return tf.keras.losses.binary_crossentropy(y_true = y, y_pred = y_)
bce = tf.keras.losses.BinaryCrossentropy(from_logits = True)
loss = bce(y_true=y, y_pred=y_)
return loss
def compute_gradients(model, inputs, targets):
'''
Function to compute the gradients for optimizing
model
'''
with tf.GradientTape() as t:
# t.watch(model.trainable_variables)
cost_val = cost_fn(model, inputs, targets)
return cost_val, t.gradient(cost_val, model.trainable_variables)
# Create Adam Gradient Descent optimizer-
optimizer = tf.keras.optimizers.Adam(learning_rate=0.01)
# Training loop:
# Used for plotting-
train_loss_results = []
train_accuracy_results = []
# An epoch is one pass through the dataset
num_epochs = 1000
for epoch in range(num_epochs):
epoch_loss_avg = tf.keras.metrics.Mean()
# epoch_accuracy = tf.keras.metrics.SparseCategoricalAccuracy()
epoch_accuracy = tf.keras.metrics.BinaryAccuracy()
# Training loop - using batches of one example-
for x, y in train_dataset:
# Optimize model-
cost_val, grads = compute_gradients(model, x, y)
optimizer.apply_gradients(zip(grads, model.trainable_variables))
# Keep track of progress-
epoch_loss_avg(cost_val) # add current batch cost/loss
# Compare accuracy of predicted label to actual label-
epoch_accuracy(y, model(x))
# End of each epoch-
train_loss_results.append(epoch_loss_avg.result())
train_accuracy_results.append(epoch_accuracy.result())
if epoch % 50 == 0:
print("\nepoch = {0}, cost = {1:.4f} & accuracy = {2:.4f}\n".format(epoch, epoch_loss_avg.result(), epoch_accuracy.result()))
上述代码存在的问题是:
在每个时期使用“ for”循环进行训练需要更多的时间,而不是如果我不使用下面的代码
model.compile(optimizer ='adam',loss ='binary_crossentropy',metrics = ['accuracy'])
model.fit(train_dataset,epochs = 50)