Выбор конфигурации tensorflow сети. Вопросы новичка

Только начинаю изучать TensorFlow keras работаю в Google colab. Немного разобрался с простейшими нейросетями и тут же возникла прикладная задача, описание подобных задач в примерах не нашел, прошу помощи сообщества!

Нижеприведенный пример упрощенный, на самом деле задача несколько сложнее, вместо чисел будут массивы с изображениями, но подход нужен именно такой, я не могу использовать классический метод обучения сети с набором [Цель]: [Верный ответ], мне обязательно нужно обучать сеть используя самописный Loss (или что-то в этом духе)

Задача:

  1. Формируем массив чисел по определенному правилу - назовем их "Паттерны" - это константы, они не меняются в ходе обучения. im_const_tensor
  2. Для обучения сети формируем число Цель = сумме нескольких случайно выбранных Паттернов (каждый Паттерн участвует в сумме не более одного раза) true_Pic
  3. На вход сети подаем Цель
  4. Сеть возвращает Цепочку - массив с номерами Паттернов, которые нужно просуммировать, чтобы получить Цель. pred_Pic
  5. Как результат работы сети, мне нужна именно Цепочка!

Возникает мысль, что нужно использовать самописный Loss на базе tf.einsum в котором суммируется Цепочка*Паттерны: Loss: res = true_Pic - tf.einsum('i,i->', im_const_tensor[0], pred_Pic[0,0]),

где Цепочка это массив из 0 и 1, той же размерности что и Паттерны. Если 1, то Паттерн участвует в итоговой сумме для получения Цели, если 0 - то не участвует.

Но при запуске обучения, я получаю: No gradients provided for any variable

Код:

# Тут импортируется немного "лишнего", использовал для отладки
import tensorflow as tf
import glob
import matplotlib
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import os
import PIL
import math
from tensorflow.keras import layers
from tensorflow.keras.layers import *
from tensorflow.keras.models import *
import time
import random
tf.config.run_functions_eagerly(True)

tf.data.experimental.enable_debug_mode() # Не понимаю почему TF просит меня использовать данную директиву

# Подготовка данных
Pins_N = 20
PicSA_N = 90

im_const = []

# Заполняем массив патернов
for A in range(Pins_N-1):
  for B in range(A+1, Pins_N):
    t = 0.0
    for C in range(A, B):
      t += 10**C
    im_const.append(t)
print(im_const)

# Генерируем целевое число случайной суммой патернов
R_N = random.randint(4, Pins_N-5)
im_const_t = im_const[:]
noize_Pic = 0.0
for A in range(R_N):
  R_i = random.randint(4, len(im_const_t))
  Val_t = im_const_t[R_i]
  noize_Pic += Val_t
  im_const_t.remove(Val_t)
print(noize_Pic)

# noize_Pic_tenzor = tf.random.normal([1, 1])
noize_Pic_tenzor = tf.constant(noize_Pic,shape=(1,1), dtype=tf.float32)
# noize_Pic_tenzor = tf.convert_to_tensor(noize_Pic, dtype=tf.float32)
print(noize_Pic_tenzor)

# Сеть смоделирована "от балды", наверняка у нее более сложная структура,
# но пока я не пронимаю что идет не так с No gradients provided for any variable
def make_pic_koef_Model():
  model = tf.keras.models.Sequential()
  model.add(tf.keras.layers.InputLayer(input_shape=(1,1)))
  model.add(tf.keras.layers.Dense(1000, activation='relu'))
  model.add(tf.keras.layers.Dense(190, activation='sigmoid'))
  model.add(tf.keras.layers.LayerNormalization(axis=1)) 
  model.add(tf.keras.layers.Lambda(lambda x: tf.round((x+1)/2))) #На выходе нужны 0 и 1
  model.summary()
  return model

# Отладка
Pic_summator = make_pic_koef_Model()
# tf.keras.utils.plot_model(Pic_summator)
Test_= Pic_summator(noize_Pic_tenzor, )
print(Test_[0,0])

im_const_tensor = tf.convert_to_tensor([im_const])
# print(im_const_tensor[0])
def loss_Pic(true_Pic, pred_Pic):
  print('loss_Pic-start')
  # s = 0.0
  # i = 0
  # print(pred_Pic[0,0])
  # for A in pred_Pic[0,0]:
  #   s += im_const[i] * A
  #   i += 1

  res = true_Pic - tf.einsum('i,i->', im_const_tensor[0], pred_Pic[0,0])
  print('loss_Pic-res')
  print(res)
  return res

Pic_summator.compile(
    loss = loss_Pic,
    metrics = 'accuracy',
    optimizer='Adam'
)

Pic_summator.fit(noize_Pic_tenzor, noize_Pic_tenzor, epochs=100)

Уточнение, это тестовый пример, рабочую модель нужно будет обучать на разных Целях, и Цель не будет точно соответствовать сумме Патернов.

Т.е., нужно будет делать модель, где работа сети выдает Цепочку, которая позволяет сделать сумму Паттернов, наиболее близкую к указанной случайно сгенерированной Цели, но это сложные сравнения, я намеренно опустил их в текущем примере, чтобы не отвлекаться от сути текущей проблемы.


Ответы (0 шт):