这是自定义损失函数:
def customloss(y_t,y_p):
with tf.GradientTape(persistent=True) as g:
with tf.GradientTape(persistent=True) as tape:
op=model(ip)
gradi=tape.batch_jacobian(op, ip)
gradi2=g.batch_jacobian(gradi, ip)
x=ip[:,0]
y=ip[:,1]
uxx=gradi2[:,0,0,0]
uyy=gradi2[:,0,1,1]
gradi
l1=tf.reduce_mean((uxx+uyy+1)**2)
l2=tf.reduce_mean((op[10000:11000])**2)
return l1+l2
(我给出了输入数组的 10000:11000 作为边界上的点:l2 是边界条件上的损失)
这是网络:
model=Sequential()
model.add(Dense(10, input_shape=(2,), activation='relu'))
for i in range(3):
model.add(Dense(50, activation='tanh'))
model.add(Dense(1))
请注意,大多数解决方案在该字段上具有负值。
这是为什么呢?是负解。一个有效的解决方案,以及如何找到正确的解决方案。?
我尝试过 8 层和 12 层、不同宽度的更深网络。这些似乎都没有帮助。
还尝试在损失函数中添加一些东西来惩罚负解,但它变得混乱,并且每次网络都会收敛到不同的解决方案。
我不认为batch_jacobian是你想要使用的函数。
这里是 TF2 上的 PDE 部分使用 eager 模型来帮助您的示例:
# loss function over the domain that computes the residuals
def lossDom(X,model):
# 'recording' the operations
# to unroll the computational graph for gradient calculation
with tf.GradientTape(persistent=True) as tape:
x , y = tf.Variable(X[:,0]) , tf.Variable(X[:,1])
# making predictions
u = model(tf.stack([x,y],axis=1))
# first derivatives
u_x = tape.gradient(u,x)
u_y = tape.gradient(u,y)
# second derivatives
u_xx = tape.gradient(u_x,x)
u_yy = tape.gradient(u_y,y)
# values of source term
fvals = f(X)
return u_xx + u_yy - fvals
X 表示大小为 (N,2) 的张量,包含有关 pde 的点。需要添加狄利克雷边界条件。有些会在偏微分方程损失中使用边界点。您可以尝试这两种方法,看看哪种方法效果最好。