解決Keras 自定義層時遇到版本的問題
阿新 • • 發佈:2020-06-17
在2.2.0版本前,
from keras import backend as K from keras.engine.topology import Layer class MyLayer(Layer): def __init__(self,output_dim,**kwargs): self.output_dim = output_dim super(MyLayer,self).__init__(**kwargs) def build(self,input_shape): # 為該層建立一個可訓練的權重 self.kernel = self.add_weight(name='kernel',shape=(input_shape[1],self.output_dim),initializer='uniform',trainable=True) super(MyLayer,self).build(input_shape) # 一定要在最後呼叫它 def call(self,x): return K.dot(x,self.kernel) def compute_output_shape(self,input_shape): return (input_shape[0],self.output_dim)
2.2.0 版本時:
from keras import backend as K from keras.layers import Layer class MyLayer(Layer): def __init__(self,input_shape): # Create a trainable weight variable for this layer. self.kernel = self.add_weight(name='kernel',self).build(input_shape) # Be sure to call this at the end def call(self,self.output_dim)
如果你遇到:
<module> from keras.engine.base_layer import InputSpec ModuleNotFoundError: No module named 'keras.engine.base_layer'
不妨試試另一種引入!
補充知識:Keras自定義損失函式在場景分類的使用
在做影象場景分類的過程中,需要自定義損失函式,遇到很多坑。Keras自帶的損失函式都在losses.py檔案中。(以下預設為分類處理)
#losses.py #y_true是分類的標籤,y_pred是分類中預測值(這裡指,模型最後一層為softmax層,輸出的是每個類別的預測值) def mean_squared_error(y_true,y_pred): return K.mean(K.square(y_pred - y_true),axis=-1) def mean_absolute_error(y_true,y_pred): return K.mean(K.abs(y_pred - y_true),axis=-1) def mean_absolute_percentage_error(y_true,y_pred): diff = K.abs((y_true - y_pred) / K.clip(K.abs(y_true),K.epsilon(),None)) return 100. * K.mean(diff,axis=-1) def mean_squared_logarithmic_error(y_true,y_pred): first_log = K.log(K.clip(y_pred,None) + 1.) second_log = K.log(K.clip(y_true,None) + 1.) return K.mean(K.square(first_log - second_log),axis=-1) def squared_hinge(y_true,y_pred): return K.mean(K.square(K.maximum(1. - y_true * y_pred,0.)),axis=-1)
這裡面簡單的來說,y_true就是訓練資料的標籤,y_pred就是模型訓練時經過softmax層的預測值。經過計算,得出損失值。
那麼我們要新建損失函式totoal_loss,就要在本檔案下,進行新建。
def get_loss(labels,features,alpha,lambda_c,lambda_g,num_classes): #由於涉及研究內容,詳細程式碼不做公開 return loss #total_loss(y_true,y_pred),y_true代表標籤(類別),y_pred代表模型的輸出 #( 如果是模型中間層輸出,即代表特徵,如果模型輸出是經過softmax就是代表分類預測值) #其他有需要的引數也可以寫在裡面 def total_loss(y_true,y_pred): git_loss=get_loss(y_true,y_pred,alpha=0.5,lambda_c=0.001,lambda_g=0.001,num_classes=45) return git_loss
自定義損失函式寫好之後,可以進行使用了。這裡,我使用交叉熵損失函式和自定義損失函式一起使用。
#這裡使用vgg16模型 model = VGG16(input_tensor=image_input,include_top=True,weights='imagenet') model.summary() #fc2層輸出為特徵 last_layer = model.get_layer('fc2').output #獲取特徵 feature = last_layer #softmax層輸出為各類的預測值 out = Dense(num_classes,activation = 'softmax',name='predictions')(last_layer) #該模型有一個輸入image_input,兩個輸出out,feature custom_vgg_model = Model(inputs = image_input,outputs = [feature,out]) custom_vgg_model.summary() #優化器,梯度下降 sgd = optimizers.SGD(lr=learn_Rate,decay=decay_Rate,momentum=0.9,nesterov=True) #這裡面,剛才有兩個輸出,這裡面使用兩個損失函式,total_loss對應的是fc2層輸出的特徵 #categorical_crossentropy對應softmax層的損失函式 #loss_weights兩個損失函式的權重 custom_vgg_model.compile(loss={'fc2': 'total_loss','predictions': "categorical_crossentropy"},loss_weights={'fc2': 1,'predictions':1},optimizer= sgd,metrics={'predictions': 'accuracy'}) #這裡使用dummy1,dummy2做演示,為0 dummy1 = np.zeros((y_train.shape[0],4096)) dummy2 = np.zeros((y_test.shape[0],4096)) #模型的輸入輸出必須和model.fit()中x,y兩個引數維度相同 #dummy1的維度和fc2層輸出的feature維度相同,y_train和softmax層輸出的預測值維度相同 #validation_data驗證資料集也是如此,需要和輸出層的維度相同 hist = custom_vgg_model.fit(x = X_train,y = {'fc2':dummy1,'predictions':y_train},batch_size=batch_Sizes,epochs=epoch_Times,verbose=1,validation_data=(X_test,{'fc2':dummy2,'predictions':y_test}))
寫到這裡差不多就可以了,不夠詳細,以後再做補充。
以上這篇解決Keras 自定義層時遇到版本的問題就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。