我正在處理一篇論文,它實作了一個具有自定義損失函式的自動編碼器來處理振動信號。
我無法在 keras 上實作它。他們將“最大相關熵”作為損失函式來避免信號上的背景噪聲問題。
這是描述:
Gaussian kernel是correntropy中最流行的Mercer核,定義為

其中 r 是內核大小。然后,可以通過最大化以下函式來設計新的自動編碼器損失函式:

由于我從未實作過自定義損失函式,因此我在 python 中遇到了數學問題。內核用于我需要實作的損失函式。這就是我所擁有的:
資料集.npz
file = np.load('./data/CWRU_48k_load_1_CNN_data.npz') # Numpy Array
data = file['data'].reshape(len(file['data']), 1024)
labels = file['labels']
category_labels = np.unique(labels)
labels = pd.Categorical(labels, categories = category_labels).codes
train_data, test_data, train_labels, test_labels = train_test_split(data, labels, test_size = int(data.shape[0]*0.2), random_state = 100, stratify = labels)
train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)
# Data shape. Sample Len: 1024. Outputs/Classifications: 10
print(train_data.shape, train_labels.shape, test_data.shape, test_labels.shape)
#(3680, 1024) (3680, 10) (920, 1024) (920, 10)
act_func = 'relu'
out_func = 'softmax'
k_inic = 'glorot_uniform'
def create_model(shape=[512, 100], loss_func='mse'):
model = Sequential()
for shape_size in shape:
model.add(Dense(shape_size, activation=act_func, kernel_initializer=k_inic))
model.add(Dense(10, activation=out_func, kernel_initializer=k_inic))
model.compile(loss=loss_func, optimizer=keras.optimizers.Adam(), metrics=["accuracy"])
model.build(input_shape=(None, 1024))
return model
BATCH_SIZE = 45
EPOCHS = 200
VALIDATION_SPLIT = 0.05
# Design Mercer Kernel
def kernel(x, sigma=1):
return (1/(K.sqrt(2*np.pi)*sigma))*K.exp((-(x*x)/(2*sigma*sigma)))
# Use Mercer Kernel on Maximum Correntropy for loss function
def correntropy(y_true, y_pred):
sum_score = 0.0
for i in range(len(y_true)):
sum_score = kernel(y_true[i] - y_pred[i])
sum_score = sum_score/len(y_true)
return -sum_score
# Create AutoEncoder model with my custom loss function
model = create_model(shape=[512, 100], loss_func=correntropy)
history = model.fit(train_data, train_labels, epochs = EPOCHS, batch_size = BATCH_SIZE, validation_data=(test_data, test_labels),
callbacks = callbacks.callbacks, verbose = 0)
res = model.evaluate(test_data, test_labels, batch_size = BATCH_SIZE, verbose = 0)[1]
但我有這個錯誤:
AttributeError: in user code:
/home/user/.local/lib/python3.8/site-packages/keras/engine/training.py:853 train_function *
return step_function(self, iterator)
/tmp/ipykernel_95935/2003563015.py:26 correntropy *
sum_score = kernel(y_true[i] - y_pred[i])
/tmp/ipykernel_95935/2239884018.py:20 kernel *
return (1/(K.sqrt(2*np.pi)*sigma))*K.exp((-(x*x)/(2*sigma*sigma)))
/home/user/.local/lib/python3.8/site-packages/tensorflow/python/util/dispatch.py:206 wrapper **
return target(*args, **kwargs)
/home/user/.local/lib/python3.8/site-packages/keras/backend.py:2539 sqrt
zero = _constant_to_tensor(0., x.dtype.base_dtype)
AttributeError: 'float' object has no attribute 'dtype'
錯誤似乎在kernel,但是我如何修復以使用張量?
print(y_true)
print(y_pred)
>> Tensor("IteratorGetNext:1", shape=(None, 10), dtype=float32)
>> Tensor("sequential_161/dense_491/Softmax:0", shape=(None, 10), dtype=float32)
uj5u.com熱心網友回復:
我在您的代碼中注意到 3 個主要內容:
- 您正在組合來自不同包(K,np)的數學函式。盡可能堅持使用原生 tensorflow 函式(例如 tf.math.reduce_sum)。有很多東西。檢查檔案以獲取概述
- 自定義損失函式應該轉換成與 tensorflow 圖兼容的函式,就像把
tf.function裝飾器放在它前面一樣簡單。看這里 - 回圈通常做得不好。盡可能矢量化你的函式。
總之,我認為這樣的事情應該可以作業(沒有測驗過):
import tensorflow as tf
tf_2pi = tf.constant(tf.sqrt(2*np.pi), dtype=tf.float32)
@tf.function
def kernel(x, sigma=1):
return (1 / (tf_2pi * sigma)) * tf.exp((-(x * x) / (2 * sigma * sigma)))
@tf.function
def correntropy(y_true, y_pred):
return -tf.math.reduce_mean(kernel(y_true - y_pred))
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/424837.html
