Conversation
…ain. This was necessary to avoid merge conflicts caused by vectorization changes and other
| input_size: int = 1, | ||
| block_size: Optional[list] = None, | ||
| output_size: int = 1, | ||
| # TODO: config |
degann/aliases.py
Outdated
| LossFunc: TypeAlias = Callable[ | ||
| [tf.keras.Model, tf.GradientTape, tf.Tensor, tf.Tensor], float | int | ||
| ] No newline at end of file |
There was a problem hiding this comment.
Мне больше нравится
class PhysicLoss:
def __call__(self, model: tf.keras.Model, tape: tf.GradientTape, x: tf.Tensor) -> float | int:
tape.watch(x)
u = model(x)Тогда можно использовать следующим образом
class SinLoss_phys(PhysicLoss):
""" y'' + 100y = 0, y(0) = 0, y'(0) = 10 """
def __call__(self, model: tf.keras.Model, tape: tf.GradientTape, x: tf.Tensor) -> float | int:
super().__call__(model, tape, x)
u_x = tape.gradient(u, x)
u_xx = tape.gradient(u_x, x)
u_left = u_xx + 100 * u
u_right = 0
return mse(u_right - u_left)
class SinLoss_boundary(PhysicLoss):
""" y'' + 100y = 0, y(0) = 0, y'(0) = 10 """
def __call__(self, model: tf.keras.Model, tape: tf.GradientTape, x: tf.Tensor) -> float | int:
x = 0
super().__call__(model, tape, x)
u_left = u
u_right = 0
return mse(u_right - u_left)
class SinLoss_boundary2(PhysicLoss):
""" y'' + 100y = 0, y(0) = 0, y'(0) = 10 """
def __call__(self, model: tf.keras.Model, tape: tf.GradientTape, x: tf.Tensor) -> float | int:
x = 0
super().__call__(model, tape, x)
u_x = tape.gradient(u, x)
u_left = u_x
u_right = 10
return mse(u_right - u_left)There was a problem hiding this comment.
Или тут есть какие-то минусы, которые я не вижу?
| self._name = "PINN" | ||
| if block_size is None: | ||
| block_size = [] | ||
|
|
||
| decorator_params: List[Optional[Dict]] = [None] | ||
| if "decorator_params" in kwargs.keys(): |
There was a problem hiding this comment.
Это всё здесь не надо. По идее Вам достаточно сказать
self.network = network
# than we could use network like this
self.network.to_cpp()
self.network.call()
self.network.compile()
etc.
| # TODO: ignore the Tensorflow types here, | ||
| # because we pass exactly the specified parameters | ||
| # to degann.IModel.train in fit(). | ||
| def train_step(self, data: tuple[tf.Tensor, tf.Tensor]): # type: ignore |
There was a problem hiding this comment.
Вам скорее надо написать кастомную функцию обучения, т.к. fit требует передавать в себя данные, а по базе Вы можете обучать pinn без данных.
Опять же, Вам надо считать значение уравнения в каких-то точках, т.е. как будто надо x передавать. А можно создавать его каждый раз разным при обучении. Ещё можно сделать его аттрибутом нейронки
| if loss is None: | ||
| loss = tf.constant(0) | ||
| # TODO: refactor | ||
| phys_loss = tf.constant(0) |
There was a problem hiding this comment.
Рекомендую просто сделать список self.phys_losses и тогда циклом по ним проходится. У них всё равно одинаковая сигнатура
| Best neural network presented as a dictionary | ||
| """ | ||
| best_net = None | ||
| # TODO: may be float("inf")? |
| LossFunc: TypeAlias = Callable[ | ||
| [tf.keras.Model, tf.GradientTape, tf.Tensor, tf.Tensor], float | int | ||
| ] |
| class DenseParams(BaseNetParams): | ||
| pass |
There was a problem hiding this comment.
Не совсем понимаю, у DenseParams есть же параметры
Use fit instead of custom logic if data provided
added a class implementing physically informed neural networks. The class works with IModel.