Обновить
3

Пользователь

2
Подписчики
Отправить сообщение

Опять MNIST? Когда уже перейдут от детских игрушек к чему-нибудь более востребованному?
Я так понимаю что всё это "дышащее" позиционируется как что-то очень "умное".
Тогда подходящие задачи это поиск закономерностей в сложной среде, агентнось, самообучение.
И разумеется это должно давать результаты лучше не дышащих. Жду.

Без компиляции на минуту дольше.

Скрытый текст
from torchvision import transforms
import datetime as dt
import torch
from torch.utils.data import Dataset, DataLoader
import torch.nn as nn
import math
import os
import im2data

fileIm = "1.png"
n = 240000
#rm = 2             # общее число признаков Раунд 1
#rm = 10            # общее число признаков Раунд 2,3
#rm = 500           # общее число признаков Раунд 4,5     
#rm = 1000          # общее число признаков Раунд 6,7
rm = 2000          # общее число признаков Раунд 8,9       
#rotate = False     # поворот пространства признаков Раунд 1,2,4,6,8
rotate = True     # поворот пространства признаков Раунд 3,5,7,9

EPOCHS = 200       # раунд 1,2,3
# EPOCHS = 400       # раунд 4,5
# EPOCHS = 1000       # раунд 6,7
# EPOCHS = 2000       # раунд 8,9

use_gpu = True    # почему-то на моём железе, на cpu эта нейросеть работала быстрее
device = torch.device('cuda' if use_gpu and torch.cuda.is_available() else 'cpu')


print(f"Device: {device}, Загрузка данных: rm={rm}, rotate={rotate}")

im, X_train_full, X_test_new, X_train, y_train, X_test, y_test, rot_mat = \
    im2data.obraz2d2(fileIm, n, rm, rotate=rotate)


class MyDataset(Dataset):
    def __init__(self, X, y):
        self.X = X
        self.y = y

    def __len__(self):
        return self.X.shape[0]
  
    def __getitem__(self, index):
        return (self.X[index], self.y[index])
    
train = MyDataset(X_train,y_train)
test = MyDataset(X_test, y_test)
trainset = DataLoader(train, batch_size=500, shuffle=True)
testset = DataLoader(test, batch_size=30000, shuffle=False)

act = nn.Tanh()

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(rm, 3)
        self.fc2 = nn.Linear(3, 30)
        self.fc3 = nn.Linear(30, 30)
        self.fc4 = nn.Linear(30, 30)
        self.fc5 = nn.Linear(30, 30)
        self.fc6 = nn.Linear(30, 30)
        self.fc7 = nn.Linear(30, 30)
        self.fc8 = nn.Linear(30, 30)
        self.fc9 = nn.Linear(30, 30)
        self.fc10 = nn.Linear(30, 30)
        self.fc11 = nn.Linear(30, 1)

    def forward(self, x):
        x = self.fc1(x)
        x = self.fc2(x)
        x = act(x * self.fc3(x))
        x = act(x + self.fc4(x))
        x = act(x * self.fc5(x))
        x = act(x + self.fc6(x))
        x = act(x * self.fc7(x))
        x = act(x + self.fc8(x))
        x = act(x * self.fc9(x))
        x = act(x + self.fc10(x))
        return self.fc11(x)

# torch.manual_seed(0)
startL = dt.datetime.now()
model = Net().to(device)
torch.set_float32_matmul_precision('high')
model = torch.compile(model, mode="reduce-overhead")

# criterion = nn.CrossEntropyLoss()
criterion = nn.MSELoss()
# criterion = nn.NLLLoss()

optimizer = torch.optim.Adam(model.parameters(), lr=0.003)
# optimizer = torch.optim.SGD(model.parameters(), lr=0.02, momentum=0.9)
scheduler = torch.optim.lr_scheduler.MultiplicativeLR(
    optimizer, lambda epoch: 0.98
)

train_loss = []
val_loss = []
for epoch in range(EPOCHS):
    start = dt.datetime.now()
    print(f'Эпоха: {epoch}', end=' ')
    mean_loss = 0
    batch_n = 0
    for X, y in trainset:
        model.zero_grad()
        output = model(X.to(device))

        loss = criterion(output, y.to(device))
        loss.backward()
        optimizer.step()

        mean_loss += loss
        batch_n += 1

    with torch.no_grad():
        mean_loss /= batch_n
        mean_loss = math.sqrt(mean_loss)
        scheduler.step()
        train_loss.append(mean_loss)
        print(f'Ошибка обучения, RMSE: {mean_loss:.4f}, {dt.datetime.now() - start} сек')

    mean_loss = 0
    batch_n = 0
    with torch.no_grad():
        for X, y in testset:
            output = model(X.to(device))
            loss = criterion(output, y.to(device))

            mean_loss += loss
            batch_n += 1
    
    mean_loss /= batch_n
    mean_loss = math.sqrt(mean_loss)
    val_loss.append(mean_loss)
    print(f'Ошибка валидации, RMSE: {mean_loss:.4f}, lr: {optimizer.param_groups[0]["lr"]:.5f}')

train_time = dt.datetime.now() - startL

# Проверка результата
start = dt.datetime.now()
var = model(X_test_new.to(device))
pred_time = dt.datetime.now() - start
var[var<0] = 0
var[var>1] = 1
var = var.reshape(im.shape[0],im.shape[1])
var = var.to('cpu')

# Ошибка
rmse_full = torch.mean((var - im) ** 2) ** 0.5
rmse_full = rmse_full.item()

print(f'{rmse_full:.4f}, {train_time}, {pred_time}')

Ещё улучшил. И сделал слои как в PHC.
Эпоха: 199 Ошибка обучения, RMSE: 0.0197, 0:00:02.415678 сек Ошибка валидации, RMSE: 0.0209, lr: 0.00005 0.0204, 0:09:54.106488, 0:00:03.664881

class Block(nn.Module):
    def __init__(self, in_dim, expand, out_dim):
        super().__init__()
        self.i_l = nn.Linear(in_dim, in_dim * expand * 2)
        self.o_l = nn.Linear(in_dim * expand, out_dim)
        self.act = nn.Tanh()

    def forward(self, x):
        x, y = torch.chunk(self.i_l(x), 2, -1)
        return self.o_l(self.act(x * y))

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(rm, 3)
        self.fc2 = nn.Linear(3, 50)
        self.fc3 = Block(50, 2, 50)
        self.fc4 = Block(50, 2, 50)
        self.fc5 = Block(50, 2, 50)
        self.fc6 = Block(50, 2, 50)
        self.fc10 = nn.Linear(50, 1)

    def forward(self, x):
        x = self.fc1(x)
        x = self.fc2(x)
        x = self.fc3(x)
        x = self.fc4(x)
        x = self.fc5(x)
        x = self.fc6(x)
        x = self.fc10(x)
        return x

scheduler = torch.optim.lr_scheduler.MultiplicativeLR(
    optimizer, lambda epoch: 0.98
)

    with torch.no_grad():
        mean_loss /= batch_n
        mean_loss = math.sqrt(mean_loss)
        scheduler.step()

Это все изменения.

Улучшив "17_test_nnet3.py" думаю я разгромил PHC:
Device: cuda, Загрузка данных: rm=2000, rotate=True
Эпоха: 199 Ошибка обучения, RMSE: 0.0130, 0:00:02.410549 сек
Ошибка валидации, RMSE: 0.0143
0.0138, 0:10:01.892468, 0:00:03.905147

Не совсем правильно думать, что у ИИ среднее мнение. LLM - это актёр и полиглот. Ей легко подтвердить или опровергнуть почти любое мнение. Большинство точек зрения, за и против них, он видел при обучении. Как было сказано, в вопросе уже половина ответа. Надо только подыграть. Для ИИ не проблема поддержать любую тему, которой обучен.

По коду:
get_batch_streaming не создаёт маску падов (и вообще нигде пады не проверяются).
random.choice(buffer) может выбрать теже примеры повторно или не выбрать вообще.
На каждый вызов создаётся новый buffer = deque(), берёт 200 примеров, создаёт батч из 4, берёт ещё 1. Это делает предыдущие проблемы несущественными.
В roneneldan/TinyStories - 2141709 train примеров. Делим на 201 = каждые 10655 шагов датасет начинается сначала.

block_size 512 * 4.5 средняя длина токена (из предыдущей статьи) = 2304 знака на пример. Так что ~80% примеров приходится сильно падить (средняя длина примера ~1000).
val_loss.item() < best_val_loss делается на одном батче из разных примеров. Так что результат полуслучайный.

Итого:
Пады в loss не проверяются (пады легко предсказываются), каждые 10655 шагов рестарт, best_val_loss полуслучайный, черрипикинг. Это всё приводит к сильному занижению потерь. Иначе как Говно я это назвать не могу.

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

На "HuggingFaceFW/fineweb-edu" я не сравнивал. Но код со времён TinyStories не менялся. Так что всё актуально.

(Напоминаем, что другие модели Gemini вы можете протестировать, перейдя на Google AI Studio по ссылке и через API совершенно бесплатно)

Он прав. Разница как между "построить ещё один автомобильный завод" и "обклеить машину винилом".

В статье сказано:
"s1, работает аналогично передовым моделям рассуждений, таким как o1 от OpenAI и R1" - то есть рассуждает.
"s1 является дистилляцией одной из моделей рассуждений Google, Gemini 2.0 Flash Thinking" - буквально использовали ответы модели.
"с помощью процесса, называемого контролируемой тонкой настройкой (SFT)" - самый базовый метод тюнинга.

Итого это была ленивая и тупая работа бездарей.

Совсем недавно давал этой священной троице пару функций на оптимизацию:
1. Построение 2D AABB для области видимости. Это можно было легко переписать на SSE.
2. Построение 2D эллипса, сделанную тупо через Sin/Cos. Особенностями было использование TRIANGLELIST для D3D9 и поворот вокруг центра + поворот текстуры. Тут мне пришло на ум целых 6 возможных оптимизаций. Поворот 2х2 матрицей (проще чем Sin/Cos), рекуррентный поворот вектора, использование симметрии, вычисление только нужной части преобразований (если не все функции задействованы), использование TRIANGLEFAN, SSE.

Ни один "думальщик" не подумал и не сделал ни одну оптимизацию. Но исковеркали форматирование, засрали комментариями, а o3 ещё поприкалывался надо мной(в духе: оптимизация тебе не поможет, если никто не сможет разобраться в коде. Сохрани нервы другим разрабам.)
Зато 1206 сразу сделал 2 (поворот матрицей, рекуррентный поворот вектора) и упомянул о TRIANGLEFAN, SSE для второй задачи (первую не предлагал) + нашёл бесполезную строку и ещё много о чём предупредил.

Другой случай: Сделал автономного агента для экспериментирования над RNN. Gemini thinking оказался вообще не дееспособен. Копировал и запускал исходный код без изменений. Раз за разом. В надежде на изменения... безумие. Даже 1.5 flash лучше справлялся. Он реально экспериментировал, сравнивал, выбирал.

И так с любой моей задачей. Я пришёл к выводи что "думальщики" лишь имитируют размышления. А результат у них тот же или хуже обычных. Но ещё токенов больше тратят.

Да я понял и согласен. Но я не провожу границы между тогда и сейчас. Сейчас всё тоже сложение векторов в основе только надстроек стало больше. И дорогу прокладывали эвристически тогда и сейчас.

Ну да Word2Vec стал известен относительно недавно.
Королева = король - мужчина + женщина.
Нищеброд = король + женщина - корона.
Многозначность была.


Жаль только что так долго придумать не могли эту простейшую идею.
Но операции над векторами в нейросетях были и никуда не делись.
Основа нейросетей это умножение матриц. Так что математика тоже никуда не девалась.

LSTM придумали в 1997 году. А RNN в принципе ещё раньше.
А всего несколько лет назад придумали Транс (2017).
И что значит "однозначно сопоставляется с вектором" ?
Нейросети имеют вероятностную природу. На входе и сейчас токены однозначно сопоставляется. А на выходе этого давно никто не ждёт.

Когда рассказчик дерьмовый, конечно, не понятно (я не про статью, я её не читал).
Однако, как я считаю, понять это довольно просто.
Эмбеддинги - это способ представить класс/понятие через вектор.
"слово" (класс) = [0.3, -0.2, 0.6] (вектор)
А сумма векторов здесь не работает, потому что теряется информация о порядке (например, "вопрос про" или "про вопрос"). Потому придумали RNN и Транс. А нейросеть - это просто функция с большим количеством связей (настраиваются весами). И обратное распространение как способ подбора весов.

Конечно. Но мой посыл был в том, что "рассуждатели" полностью провалились там, где должны были иметь преимущество. В решении нестандартных задач.

Результат выглядит как: Взяли результаты чужого труда. Видимо, это обошлось им в $30. Взяли халявную модель и затюнили($20). Получилась сенсация за $50.

По моему опыту все эти модели "рассуждений" и тесты - полный мусор.
На моих задачах(программирование + немного математики) они рассуждают в среднем 6 секунд. И выдают абсолютно бесполезный ответ. А вот gemini-exp-1206 справляется лучше всех рассуждателей вместе взятых. Отмечу, что мои задачи как раз не типовые.

Блин. Да тут на самом деле всё очевидно.
Сначала в сеть закачивают ~15 терра-токенов говна из интернета.
Потом чёта настраивают. Потом приходит неизвестно кто.
И задаёт вопрос про своих тараканов в голове. Плюс высокая температура сэмплера.
Ну результат закономерный. Сетка теряется в догадках чё от неё хотят.

Ссылки на все статьи есть. А что касается ZNorm то в статье есть результаты тестов.
И там довольно просто. Кому надо сами могут проверить.

Да нормально всё. Наконец то статья от того кто знает о чём говорит.
Надоели дурацкие тексты про OpenAI и прочих корпоратов.
Или - как собрать GPT2 из говна и палок для чайников.

Информация

В рейтинге
6 516-й
Откуда
Россия
Зарегистрирован
Активность

Специализация

Десктоп разработчик, Разработчик игр
Средний
Delphi
Win32 API
Vulkan API
DirectX
TensorFlow
Python
JavaScript
Lua
X86 asm
C++