小编给大家分享一下使用tensorflow2自定义损失函数需要注意什么,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

Keras的核心原则是逐步揭示复杂性,可以在保持相应的高级便利性的同时,对操作细节进行更多控制。当我们要自定义fit中的训练算法时,可以重写模型中的train_step方法,然后调用fit来训练模型。

这里以tensorflow2官网中的例子来说明:

importnumpyasnpimporttensorflowastffromtensorflowimportkerasx=np.random.random((1000,32))y=np.random.random((1000,1))classCustomModel(keras.Model):tf.random.set_seed(100)deftrain_step(self,data):#Unpackthedata.Itsstructuredependsonyourmodeland#onwhatyoupassto`fit()`.x,y=datawithtf.GradientTape()astape:y_pred=self(x,training=True)#Forwardpass#Computethelossvalue#(thelossfunctionisconfiguredin`compile()`)loss=self.compiled_loss(y,y_pred,regularization_losses=self.losses)#Computegradientstrainable_vars=self.trainable_variablesgradients=tape.gradient(loss,trainable_vars)#Updateweightsself.optimizer.apply_gradients(zip(gradients,trainable_vars))#Updatemetrics(includesthemetricthattrackstheloss)self.compiled_metrics.update_state(y,y_pred)#Returnadictmappingmetricnamestocurrentvaluereturn{m.name:m.result()forminself.metrics}#ConstructandcompileaninstanceofCustomModelinputs=keras.Input(shape=(32,))outputs=keras.layers.Dense(1)(inputs)model=CustomModel(inputs,outputs)model.compile(optimizer="adam",loss=tf.losses.MSE,metrics=["mae"])#Justuse`fit`asusualmodel.fit(x,y,epochs=1,shuffle=False)32/32[==============================]-0s1ms/step-loss:0.2783-mae:0.4257

这里的loss是tensorflow库中实现了的损失函数,如果想自定义损失函数,然后将损失函数传入model.compile中,能正常按我们预想的work吗?

答案竟然是否定的,而且没有错误提示,只是loss计算不会符合我们的预期。

defcustom_mse(y_true,y_pred):returntf.reduce_mean((y_true-y_pred)**2,axis=-1)a_true=tf.constant([1.,1.5,1.2])a_pred=tf.constant([1.,2,1.5])custom_mse(a_true,a_pred)tf.losses.MSE(a_true,a_pred)

以上结果证实了我们自定义loss的正确性,下面我们直接将自定义的loss置入compile中的loss参数中,看看会发生什么。

my_model=CustomModel(inputs,outputs)my_model.compile(optimizer="adam",loss=custom_mse,metrics=["mae"])my_model.fit(x,y,epochs=1,shuffle=False)32/32[==============================]-0s820us/step-loss:0.1628-mae:0.3257

我们看到,这里的loss与我们与标准的tf.losses.MSE明显不同。这说明我们自定义的loss以这种方式直接传递进model.compile中,是完全错误的操作。

正确运用自定义loss的姿势是什么呢?下面揭晓。

loss_tracker=keras.metrics.Mean(name="loss")mae_metric=keras.metrics.MeanAbsoluteError(name="mae")classMyCustomModel(keras.Model):tf.random.set_seed(100)deftrain_step(self,data):#Unpackthedata.Itsstructuredependsonyourmodeland#onwhatyoupassto`fit()`.x,y=datawithtf.GradientTape()astape:y_pred=self(x,training=True)#Forwardpass#Computethelossvalue#(thelossfunctionisconfiguredin`compile()`)loss=custom_mse(y,y_pred)#loss+=self.losses#Computegradientstrainable_vars=self.trainable_variablesgradients=tape.gradient(loss,trainable_vars)#Updateweightsself.optimizer.apply_gradients(zip(gradients,trainable_vars))#Computeourownmetricsloss_tracker.update_state(loss)mae_metric.update_state(y,y_pred)return{"loss":loss_tracker.result(),"mae":mae_metric.result()}@propertydefmetrics(self):#Welistour`Metric`objectsheresothat`reset_states()`canbe#calledautomaticallyatthestartofeachepoch#oratthestartof`evaluate()`.#Ifyoudon'timplementthisproperty,youhavetocall#`reset_states()`yourselfatthetimeofyourchoosing.return[loss_tracker,mae_metric]#ConstructandcompileaninstanceofCustomModelinputs=keras.Input(shape=(32,))outputs=keras.layers.Dense(1)(inputs)my_model_beta=MyCustomModel(inputs,outputs)my_model_beta.compile(optimizer="adam")#Justuse`fit`asusualmy_model_beta.fit(x,y,epochs=1,shuffle=False)32/32[==============================]-0s960us/step-loss:0.2783-mae:0.4257

终于,通过跳过在 compile() 中传递损失函数,而在 train_step 中手动完成所有计算内容,我们获得了与之前默认tf.losses.MSE完全一致的输出,这才是我们想要的结果。

以上是“使用tensorflow2自定义损失函数需要注意什么”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!