#python #tensorflow #machine-learning #keras #neural-network
Вопрос:
Я пытаюсь создать программу на python, которая использует машинное обучение для прогнозирования квадратного корня из числа. Я перечисляю все, что я сделал в своей программе:-
- создал csv-файл с числами и их квадратами
- извлек данные из csv в подходящие переменные (X хранит квадраты, y хранит числа)
- масштабирование данных с помощью стандартного масштабера sklearn
- построил ANN с двумя скрытыми слоями, каждый из 6 блоков (без функций активации)
- скомпилировал ANN, используя SGD в качестве оптимизатора и среднеквадратичную ошибку в качестве функции потерь
- обучил модель. Убыток составил около 0,063
- попробовал предсказать, но результат-нечто другое.
Мой фактический код:-
import numpy as np
import tensorflow as tf
import pandas as pd
df = pd.read_csv('CSV/SQUARE-ROOT.csv')
X = df.iloc[:, 1].values
X = X.reshape(-1, 1)
y = df.iloc[:, 0].values
y = y.reshape(-1, 1)
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0, test_size=0.2)
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_test_sc = sc.fit_transform(X_test)
X_train_sc = sc.fit_transform(X_train)
sc1 = StandardScaler()
y_test_sc1 = sc1.fit_transform(y_test)
y_train_sc1 = sc1.fit_transform(y_train)
ann = tf.keras.models.Sequential()
ann.add(tf.keras.layers.Dense(units=6))
ann.add(tf.keras.layers.Dense(units=6))
ann.add(tf.keras.layers.Dense(units=1))
ann.compile(optimizer='SGD', loss=tf.keras.losses.MeanSquaredError())
ann.fit(x = X_train_sc, y = y_train_sc1, batch_size=5, epochs = 100)
print(sc.inverse_transform(ann.predict(sc.fit_transform([[144]]))))
выход:- array([[143.99747]], dtype=float32)
Разве выход не должен быть 12? Почему это дает мне неправильный результат?
Я прилагаю файл csv, который я также использовал для обучения своей модели: КВАДРАТНЫЙ КОРЕНЬ.csv
Комментарии:
1. Если вы используете машинное обучение, это не прогнозирование. Это расчетливо (при условии, что ваше обучение правильное). Потому что алгоритмы машинного обучения включают математические метрики для «прогнозирования», что делает его по существу вычислительным.
2. Я все еще новичок в этой области. Мне действительно жаль, если я перепутал условия 🙁 Я думаю, что мое обучение правильное, так как потери были низкими. Я не знаю, прав ли я в этом отношении. Пожалуйста, поправьте меня, если я ошибаюсь.
3. Нет, термины, которые вы использовали, были точными. Я имею в виду, как машинное обучение работает в бэкэнде. Для математических вещей он вычисляет, а не предсказывает. Но да, функция, используемая для его запуска, называется «предсказать», так что вы правы.
Ответ №1:
TL;DR: Вам действительно нужны эти нелинейности.
Причиной того, что он не работает, может быть одна (или комбинация) нескольких причин, таких как плохой диапазон входных данных, недостатки в ваших данных, чрезмерное/недостаточное оснащение и т.д.
Однако в данном конкретном случае модель, которую вы строите, буквально не может изучить функцию, которую вы пытаетесь аппроксимировать, потому что отсутствие нелинейностей делает эту модель чисто линейной, которая не может точно аппроксимировать нелинейные функции.
Dense
Слой реализован следующим образом:
x_res = activ_func(w*x b)
где x
-входные данные слоя, w
веса, b
вектор смещения и activ_func
функция активации (если она определена).
Ваша модель, таким образом, математически становится (я использую индексы от 1 до 3 для трех плотных слоев):
pred = w3 * (w2 * ( w1 * x b1 ) b2 ) b3
= w3*w2*w1*x w3*w2*b1 w3*b2 b3
Как вы видите, полученная модель по-прежнему линейна.
Добавьте функции активации, и ваш режим также сможет изучать нелинейные функции. Оттуда поэкспериментируйте с гиперпараметрами и посмотрите, как изменится производительность вашей модели.
Ответ №2:
Причина, по которой ваш код не работает, заключается в том, что вы применяете fit_transform
его к своему набору тестов, что неверно. Вы можете исправить это, заменив fit_transform(test)
на transform(test)
. Хотя я не думаю StandardScaler
, что это необходимо, пожалуйста, попробуйте это:
import numpy as np
import tensorflow as tf
import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
N = 10000
X = np.arange(1, N).reshape(-1, 1)
y = np.sqrt(X)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0, test_size=0.2)
sc = StandardScaler()
X_train_sc = sc.fit_transform(X_train)
#X_test_sc = sc.fit_transform(X_test) # wrong!!!
X_test_sc = sc.transform(X_test)
sc1 = StandardScaler()
y_train_sc1 = sc1.fit_transform(y_train)
#y_test_sc1 = sc1.fit_transform(y_test) # wrong!!!
y_test_sc1 = sc1.transform(y_test)
ann = tf.keras.models.Sequential()
ann.add(tf.keras.layers.Dense(units=32, activation='relu')) # you have 10000 data, maybe you need a little deeper network
ann.add(tf.keras.layers.Dense(units=32, activation='relu'))
ann.add(tf.keras.layers.Dense(units=32, activation='relu'))
ann.add(tf.keras.layers.Dense(units=1))
ann.compile(optimizer='SGD', loss='MSE')
ann.fit(x=X_train_sc, y=y_train_sc1, batch_size=32, epochs=100, validation_data=(X_test_sc, y_test_sc1))
#print(sc.inverse_transform(ann.predict(sc.fit_transform([[144]])))) # wrong!!!
print(sc1.inverse_transform(ann.predict(sc.transform([[144]]))))
Комментарии:
1. БОЖЕ мой! Ваш код работает как шарм! У меня есть сомнения. Надеюсь, вы их уберете. Почему существует необходимость во внедрении гораздо более глубокой сети? Это из-за меньшего количества вводимых данных? Будет ли этого достаточно вместо увеличения единиц измерения, я увеличу эпохи? Спасибо вам 🙂
2. Поскольку ваша модель кажется немного неадекватной, вот почему я предлагаю использовать более глубокую сеть. Увеличение эпох также работает, когда модель еще не сошлась. Вы можете подтвердить это, построив график. Моя модель тоже не идеальна. Вам нужно точно настроить его и попробовать разные параметры.
3. Если это произойдет, попробуйте использовать гораздо меньшую скорость обучения.