Форум программистов, компьютерный форум, киберфорум
AI_Generated
Войти
Регистрация
Восстановить пароль

Трансферное обучение с предобученными моделями в Keras с Python

Запись от AI_Generated размещена 06.05.2025 в 21:29
Показов 1123 Комментарии 0

Нажмите на изображение для увеличения
Название: 6bd95042-0df0-43de-88f5-5096509bdef6.jpg
Просмотров: 53
Размер:	134.5 Кб
ID:	10755
Суть трансферного обучения проста: взять модель, которая уже научилась решать одну задачу, и адаптировать её для решения другой, похожей задачи. Мозг человека работает по схожему принципу. Изучив игру на пианино, мы гораздо быстрее осваиваем синтезатор. Прочитав "Войну и мир", проще понять "Анну Каренину". Нейросети тоже способны переносить полученные знания с одной задачи на другую.

В центре этой технологии лежит идея о том, что низкоуровневые признаки, которые модель извлекает из данных – края, текстуры, формы для изображений или семантические конструкции для текстов – универсальны для многих задач. Зачем заново учиться распознавать кромки и углы объектов, если эти навыки уже есть в нейронной сети, натренированной на миллионах изображений ImageNet? Преимущества такого подхода сложно переоценить. Экономия вычеслительных ресурсов порой достигает 99%. Время на обучение сокращается с недель до часов или даже минут. Можно решать задачи с малым количеством данных – сотни примеров вместо миллионов. Достигается лучшая обобщающая способность, так как модель уже "видела" множество разных примеров. А еще – снижаются требования к оборудованию, что открывает двери для экспериментов энтузиастам и небольшим командам.

Историю трансферного обучения можно проследить с начала 2000-х, хотя сама идея переиспользования знаний гораздо старше. Ранние эксперименты демонстрировали скромные успехи, но настоящий прорыв произошел в 2012-2014 годах, когда исследователи начали применять предобученные сверточные нейронные сети из ImageNet для других задач. Пионеры трансферного обучения, такие как Йошуа Бенджо и Ян ЛеКун, доказали, что даже глубинные слои сетей содержат полезные обобщенные представления.

Сегодня трансферное обучение – не просто техника, а целая парадигма в машинном обучении. Модели-тяжеловесы вроде BERT, GPT, VGG или ResNet, обученные на гигантских наборах данных ведущими лабораториями и компаниями, становятся фундаментом для множества спецализированных приложений. Эта демократизация AI позволяет сокращать путь от идеи до работающего продукта в разы.

Keras – один из фреймворков, который сделал трансферное обучение доступным для широкого круга разработчиков. С его помощью всего в несколько строк кода можно загрузить предобученную модель, заморозить часть слоев и дообучить остальные под свою задачу.

Технические основы и архитектуры



За кулисами трансферного обучения скрывается целый зоопарк архитектур нейронных сетей. Каждая из них – маленький шедевр инженерной мысли, созданный для решения определённых задач. Выбор базовой архитектуры – фундаментальное решение, которое определит возможности и ограничения всего проекта.

VGG16, разработанная в Оксфорде группой Visual Geometry Group, – классика жанра и отличный первый кандидат для экспериментов с трансферным обучением. Её архитектура поражает простотой и элегантностью: последовательность сверточных слоёв с фильтрами 3×3 и шагом 1, чередующихся с пулинговыми слоями, и три полносвязных слоя на вершине. Несмотря на 138 миллионов параметров и относительную "старость" (2014 год), VGG16 остаётся востребованной благодаря понятной структуре и предсказуемому поведению.

Но что если нам нужна сеть поглубже? Тут выходит ResNet (Residual Network) со своим революционным подходом – остаточными связями (residual connections). Суть проста: добавить к выходу слоя результат работы предыдущего слоя. Эта, казалось бы, незначительная модификация решила фундаментальную проблему обучения глубоких сетей – затухание градиентов. ResNet бывает разных "размеров": от компактной ResNet18 до монструозной ResNet152. Для трансферного обучения часто используют "золотую середину" – ResNet50.

Python
1
2
3
4
5
# Пример загрузки ResNet50 в Keras
from tensorflow.keras.applications import ResNet50
# Загружаем модель без верхних полносвязных слоев
base_model = ResNet50(weights='imagenet', include_top=False, 
                     input_shape=(224, 224, 3))
MobileNet – ответ на запрос о лёгких моделях для мобильных устройств. Её фишка – depth-wise separable convolutions. Вместо обычной свертки, требующей много вычислений, проводится две последовательные операции: сначала сверточный фильтр применяется к каждому каналу изображения отдельно, а затем полученные карты признаков комбинируются через поканальную свертку 1×1. Результат – снижение вычислительной нагрузки почти в 9 раз при сохранении приличной точности.

Inception (Google) – еще один интересный игрок в этом пространстве. Ключевая идея – параллельное применение сверток разных размеров (1×1, 3×3, 5×5) и пулинга. Такой подход позволяет сети самой "решать", какие фильтры лучше подходят для обработки разных паттернов. InceptionV3 с 23 миллионами параметров показывает отличные результаты при трансферном обучении в задачах, где важно распознавание объектов разного масштаба.

А что насчет EfficientNet? Эта архитектура — результат нейронного архитектурного поиска (Neural Architecture Search). Её особенность в сбалансированном масштабировании сети сразу по трем параметрам: глубине, ширине и разрешению входного изображения. EfficientNet задала новую планку соотношения точности и вычислительной эффективности.

Каждая из этих архитектур имеет свой уникальный набор послойных представлений. Ранние слои захватывают базовые визуальные элементы – линии, углы, текстуры. Средние – более сложные паттерны и формы. Глубокие – абстрактные высокоуровневые концепции. Именно этот иерархический подход к извлечению признаков и делает трансферное обучение таким эффективным.

Когда мы говорим о трансферном обучении, важно понимать, что происходит "под капотом" этих моделей. Предобученные сети – не просто наборы весов, а слоёные пирожки признаков различного уровня абстракции. Интересно, что даже модели, обученные на, казалось бы, узкоспециализированных данных, формируют универсальные представления, пригодные для самых разных задач. Для понимания внутренних механизмов можно визуализировать активации нейронов в разных слоях сети. Например, если подать на вход изображение кота, мы увидим, как первые слои сети активируются на простые линии и контуры, средние слои "видят" текстуру шерсти и форму ушей, а глубокие слои реагируют на концепцию "котовость". Именно эта иерархия позволяет нам перенаправить высокоуровневые признаки на новые классы.

Прелесть трансферного обучения – в его гибкости. Мы можем выбрать, насколько глубоко хотим вмешиваться в архитектуру базовой модели:

1. Feature extraction (экстракция признаков) – самый простой подход. Мы берём предобученную модель, отрезаем верхушку (классификационные слои) и используем остальную часть как фиксированный экстрактор признаков. Поверх него строим свои слои, которые обучаем под свою задачу. Базовая модель остаётся неизменной.
2. Fine-tuning (тонкая настройка) – более продвинутый вариант. После первоначального обучения новых слоёв, мы "размораживаем" часть предобученной модели (обычно более глубокие слои) и аккуратно, с малой скоростью обучения, подстраиваем их веса под наши данные.

Python
1
2
3
4
5
6
7
8
9
10
11
# Пример feature extraction в Keras
base_model = VGG16(weights='imagenet', include_top=False)
base_model.trainable = False  # Замораживаем базовую модель
 
# Строим свои слои на верхушке
model = Sequential([
    base_model,
    GlobalAveragePooling2D(),
    Dense(256, activation='relu'),
    Dense(num_classes, activation='softmax')
])
Отдельно стоит упомянуть о весах моделей. Чаще всего используются веса, полученные при обучении на ImageNet – наборе из более чем 14 миллионов изображений, размеченных по 1000 классам. Однако существуют и другие варианты предобучения, например, на наборе Places (сцены и окружения) или даже на неразмеченных данных через самоконтролируемое обучение.

Выбор базовой архитектуры – балансирование множества факторов. Нужна высокая точность? ResNet или EfficientNet. Важна скорость и компактность? MobileNet. Нужна модель, которая хорошо переносится на широкий спектр задач? InceptionV3 или VGG16. А ещё есть BERT и его производные для текстовых задач, Vision Transformers для работы с изображениями...

Keras не устанавливается - При проверке установки print(keras.__version__) вылетает с ошибками
Приветствую! Решил написать сюда. Фреймворк для обучения глубоких нейронных сетей (Keras, PyTorch)....

Keras. Машинное обучение
Приветствую, занимаюсь проектом по машинному обучению и задался вопросом... Какой алгоритм обучения...

keras speech recognition обучение нейросети для распознавания голоса
Хочу обучить свою нейросеть, записал аудиозаписи в формате .AU 2-3 секундные, но появляется ошибка...

Python keras-query-classifier
Добрый день. Изучаю python, очень буду признательна за подсказку (мучаюсь месяц, решения не нашла)....


Сравнительный анализ эффективности различных предобученных моделей на разных типах задач



Когда приходится выбирать предобученную модель для конкретной задачи, начинается настоящий квест. Что лучше: тяжеловесный ResNet с его впечатляющей точностью или шустрый MobileNet, который не заставит ваш ноутбук превратиться в сковородку? Выбор не так очевиден, как может показаться на первый взгляд.

Для классификации изображений с большим количеством классов и сложным контекстом ResNet50 и InceptionV3 выдают впечатляющие результаты. В исследовании, проведенном командой MIT "Comparative Analysis of Transfer Learning Models" (2019), ResNet50 показал точность 89.2% на наборе данных с 200 классами при трансферном обучении после предварительного обучения на ImageNet. Но за такую точность приходится платить — время инференса на CPU достигало 300мс, что делает эти модели непрактичными для мобильных приложений.

MobileNet, хоть и уступает в точности (около 85.7% на том же наборе), зато работает на порядок быстрее — всего 30-40мс на том же процессоре. Для задач, где важна скорость отклика — например, в приложениях дополненой реальности или при автоматизации на производстве — такой компромис может быть вполне оправдан.

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import matplotlib.pyplot as plt
import numpy as np
 
# Создаем простую таблицу сравнения
models = ['VGG16', 'ResNet50', 'MobileNetV2', 'InceptionV3', 'EfficientNetB0']
accuracy = [88.1, 89.2, 85.7, 88.9, 90.1]  # Точность (%)
inference_time = [420, 300, 40, 260, 120]  # Время инференса (мс)
 
# Нормализуем для визуализации
norm_acc = np.array(accuracy) / max(accuracy)
norm_time = 1 - (np.array(inference_time) / max(inference_time))  # Инвертируем, чтобы выше было лучше
 
# Визуализируем метрики
fig, ax = plt.subplots(figsize=(10, 6))
x = np.arange(len(models))
width = 0.35
 
ax.bar(x - width/2, norm_acc, width, label='Нормализованная точность')
ax.bar(x + width/2, norm_time, width, label='Нормализованная скорость')
ax.set_xticks(x)
ax.set_xticklabels(models)
ax.legend()
А что если у вас мало данных? Скажем, не миллионы изображений, а всего пара сотен? VGG16, несмотря на свою "древность", часто выигрывает в таких сценариях. Её широкие полносвязные слои и прямолинейная архитектура делают её менее склонной к переобучению на малых наборах данных. Исследователи из Стэнфорда выявили интерессную закономерность: модели с большим количеством параметров на верхних слоях (как VGG) легче адаптируются к новым доменам при малом количестве примеров.

Для задач обнаружения объектов (object detection) лидеры меняются. Здесь на первый план выходят архитектуры на базе Faster R-CNN и SSD, часто использующие ResNet или MobileNet в качестве "хребта" (backbone). Эффективность этих моделей сильно зависит от размера объектов — ResNet лучше работает с маленькими объектами благодаря более глубоким признакам, но расплачивается скоростью.

EfficientNet задал новый стандарт эффективности. В задачах классификации изображений высокого разрешения EfficientNetB7 ставит рекорды точности, достигая 91.2% на ImageNet с меньшим количеством параметров, чем у ResNet101. Но новичкам стоит начать с EfficientNetB0 или B1 — эти модели намного доступнее для экспериментов.

Интересный феномен: никакая модель не является "лучшей" для всех возможных задач. Математики доказали это в так называемой "теореме о бесплатном завтраке" (No Free Lunch Theorem). Что работает для распознавания кошек, может провалится при анализе медицинских снимков. Для задач с неструктурированными данными — например, при обработке спутниковых снимков или рентгеновских изображений — трансформерные архитектуры вроде Vision Transformer (ViT) начинают обгонять сверточные сети. Их механизм внимания позволяет обрабатывать длинные зависимости в данных, но требует значительных вычислительных ресурсов для обучения.

Существует любопытная эвристика от практиков: чем больше ваши данные похожи на ImageNet (обычные фотографии повседневных объектов), тем эффективнее будет трансферное обучение. Но что делать, если ваши данные радикально отличаются — скажем, это УЗИ-снимки или микроскопические изоброжения клеток? В таких случаях имеет смысл либо выбирать модели, предобученные на похожих доменах (медицинских изображениях), либо ограничиваться переносом только самых низкоуровневых признаков, переобучая больше слоёв. Исследователи из лаборатории Google Brain показали, что даже для радикально отличающихся доменов (например, от природных изображений к медицинским) перенос низкоуровневх признаков всё равно даёт преимущество перед обучением с нуля.

Практическая имплементация в Keras



Давайте погрузимся в реальную имплементацию трансферного обучения с помощью Keras. Этот высокоуровневый API для TensorFlow сделал создание и обучение нейронных сетей настолько простым, что порой даже не верится – неужели действительно достаточно нескольких строк кода, чтобы запрячь в свою телегу такого монстра, как ResNet?
Начнем с самых основ. Для работы нам понадобятся несколько библиотек Python:

Python
1
2
3
4
5
6
7
import tensorflow as tf
from tensorflow.keras.applications import VGG16, ResNet50, MobileNetV2
from tensorflow.keras.models import Model, Sequential
from tensorflow.keras.layers import Dense, GlobalAveragePooling2D, Dropout
from tensorflow.keras.optimizers import Adam
import numpy as np
import matplotlib.pyplot as plt
Первый шаг – загрузка предобученной модели. В Keras это делается буквально одной строкой:

Python
1
2
3
# Загружаем ResNet50, предобученный на ImageNet
base_model = ResNet50(weights='imagenet', include_top=False, 
                      input_shape=(224, 224, 3))
Параметр include_top=False указывает, что мы не хотим включать верхние полносвязные слои, которые заточены под классификацию 1000 классов ImageNet. Вместо этого мы добавим свои слои, специфичные для нашей задачи.
Теперь важный момент: нужно заморозить веса базовой модели, чтобы при обучении они не изменялись:

Python
1
2
# Замораживаем все слои базовой модели
base_model.trainable = False
Далее добавляем свои слои поверх базовой модели. Здесь есть варианты: можно использовать функциональный API или Sequential. Я предпочитаю функциональный – он гибче:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
# Берем выход базовой модели
x = base_model.output
# Добавляем глобальный пулинг
x = GlobalAveragePooling2D()(x)
# Добавляем полносвязный слой
x = Dense(256, activation='relu')(x)
# Добавляем дропаут для регуляризации
x = Dropout(0.5)(x)
# Выходной слой с софтмаксом для классификации
predictions = Dense(10, activation='softmax')(x)
 
# Создаем модель
model = Model(inputs=base_model.input, outputs=predictions)
Компилируем модель, указывая функцию потерь, оптимизатор и метрики:

Python
1
2
3
model.compile(optimizer=Adam(learning_rate=0.0001),
              loss='categorical_crossentropy',
              metrics=['accuracy'])
Я частенько использую Adam с небольшой скоростью обучения – он редко подводит. Для маленьких датасетов SGD иногда работает лучше, но требуеть больше настройки.
Теперь нам нужны данные. Допустим, у нас есть набор изображений, уже поделенный на тренировочный и валидационный:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Предположим, у нас уже есть данные
[H2]X_train, y_train, X_val, y_val[/H2]
 
# Добавим аугментацию для тренировочного набора
from tensorflow.keras.preprocessing.image import ImageDataGenerator
 
train_datagen = ImageDataGenerator(
    rescale=1./255,
    rotation_range=20,
    width_shift_range=0.2,
    height_shift_range=0.2,
    horizontal_flip=True,
    fill_mode='nearest')
 
val_datagen = ImageDataGenerator(rescale=1./255)
 
train_generator = train_datagen.flow(X_train, y_train, batch_size=32)
val_generator = val_datagen.flow(X_val, y_val, batch_size=32)
Аугментация данных – мощный инструмент против переобучения. Особенно в контексте трансферного обучения, когда набор данных может быть небольшим. Поворачивая, сдвигая и отражая изображения, мы искуственно расширяем обучающую выборку. Обучаем модель с помощью генераторов данных:

Python
1
2
3
4
5
6
history = model.fit(
    train_generator,
    steps_per_epoch=len(X_train) // 32,
    epochs=10,
    validation_data=val_generator,
    validation_steps=len(X_val) // 32)
Вот и все! Мы успешно применили трансферное обучение. Но это лишь базовая стратегия. В реальных проектах после такого первоначального обучения часто применяют тонкую настройку (fine-tuning). Для этого размораживают несколько верхних слоев базовой модели и продолжают обучение с очень низкой скоростью обучения:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Размораживаем последние несколько слоев базовой модели
for layer in base_model.layers[-10:]:
    layer.trainable = True
    
# Перекомпилируем модель с более низкой скоростью обучения
model.compile(optimizer=Adam(learning_rate=1e-5),  # Очень низкая!
              loss='categorical_crossentropy',
              metrics=['accuracy'])
 
# Продолжаем обучение еще несколько эпох
history_fine = model.fit(
    train_generator,
    steps_per_epoch=len(X_train) // 32,
    epochs=5,
    validation_data=val_generator,
    validation_steps=len(X_val) // 32)
Важная часть процесса – визуализация результатов обучения. Хороший график стоит тысячи слов, особенно когда мы пытаемся понять, что происходит с моделью во время обучения:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])
plt.title('Точность модели')
plt.ylabel('Точность')
plt.xlabel('Эпоха')
plt.legend(['Обучение', 'Валидация'], loc='lower right')
 
plt.subplot(1, 2, 2)
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('Потери модели')
plt.ylabel('Потери')
plt.xlabel('Эпоха')
plt.legend(['Обучение', 'Валидация'], loc='upper right')
plt.show()
На таких графиках как на ладони видны признаки переобучения – если линия тренировочной точности постоянно растёт, а валидационной начинает падать, пора применять дополнительную регуляризацию или останавливать обучение раньше.
После обучения обязательно нужно проверить модель на отложенном тестовом наборе – том, который модель "никогда не видела":

Python
1
2
test_loss, test_acc = model.evaluate(X_test, y_test, verbose=2)
print(f'Точность на тестовом наборе: {test_acc:.4f}')
Часто бывает полезно посмотреть, какие именно примеры модель классифицирует неверно. Иногда это выявляет смещения в данных или интересные закономерности:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Получаем предсказания
predictions = model.predict(X_test)
predicted_classes = np.argmax(predictions, axis=1)
true_classes = np.argmax(y_test, axis=1)
incorrect_indices = np.nonzero(predicted_classes != true_classes)[0]
 
# Выводим некоторые неверно классифицированные примеры
plt.figure(figsize=(10, 10))
for i, incorrect in enumerate(incorrect_indices[:9]):
plt.subplot(3, 3, i + 1)
plt.imshow(X_test[incorrect].astype(np.uint8))
plt.title(f'Предсказано: {predicted_classes[incorrect]}\nПравильно: {true_classes[incorrect]}')
plt.axis('off')
plt.tight_layout()
plt.show()
Сохранение модели – критически важная часть рабочего процесса. В Keras это делается невероятно просто:

Python
1
2
3
4
5
# Сохраняем всю модель (архитектуру + веса + состояние оптимизатора)
model.save('my_transfer_model.h5')
 
# Или только веса
model.save_weights('my_model_weights.h5')
За кулисами трансферного обучения скрывается много нюансов. Например, предобработка данных должна быть такой же, как при обучении оригинальной модели. Для большинства предобученных на ImageNet моделей это означает нормализацию пикселей к диапазону [-1, 1] или [0, 1] и, возможно, вычитание средних значений каналов. Некоторые модели, как VGG, имеют фиксированный размер входа (224x224), другие могут принимать произвольные размеры. При изменении размера стоит помнить о пропорциях – лучше вписать изоброжение в нужный размер с сохранением пропорций, чем растягивать его.

Один из трюков, который я часто использую – прогрессивная разморозка слоёв. Вместо разморозки сразу 10 или 20 слоёв, размораживать их постепенно, по 2-3 слоя за раз, обучая несколько эпох после каждого шага. Это помогает избежать разрушения предобученных весов из-за слишком больших градиентов.

Оптимизация гиперпараметров при тонкой настройке моделей



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

Самый коварный гиперпараметр — скорость обучения (learning rate). При тонкой настройке предобученных моделей нужно действовать как сапёр: осторожно и на малых скоростях. Если для обучения с нуля подходят значения порядка 1e-3, то здесь лучше начинать с 1e-5. Слишком агрессивное обучение может буквально "стереть" драгоценные веса, накопленные моделью в процессе предварительного обучения.

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Пример стратегии постепенного снижения скорости обучения
from tensorflow.keras.callbacks import ReduceLROnPlateau
 
reduce_lr = ReduceLROnPlateau(
monitor='val_loss',  # Отслеживаем валидационный лосс
factor=0.2,          # Уменьшаем скорость в 5 раз при плато
patience=3,         # Ждем 3 эпохи перед снижением
min_lr=1e-6          # Не снижаем меньше этого значения
)
 
history = model.fit(
train_generator,
epochs=20,
validation_data=val_generator,
callbacks=[reduce_lr]  # Добавляем коллбэк
)
Другой ключевой параметр — глубина разморозки модели. Тут действует принцип: чем ближе ваш датасет к оригинальному, тем меньше слоёв стоит размораживать. На практике я выработал такое эмпирическое правило: для близких доменов (например, перенос с каталога товаров на распознавание видов мебели) достаточно разморозить 10-15% верхних слоёв. Для далёких доменов (например, с фотографий на медицинские снимки) — до 30-50%.

Для автоматизации поиска оптимальных гиперпараметров на помощь приходит Keras Tuner — инструмент, который перебирает комбинации параметров по заданной стратегии. Наиболее практичны три подхода:
  1. Grid Search (полный перебор) — надежный, но затратный.
  2. Random Search (случайный поиск) — удивительно эффективен при ограниченом бюджете.
  3. Bayesian Optimization (байесовская оптимизация) — мой фаворит для поиска тонких настроек.

Методики оценки качества адаптации предобученных моделей к новым данным



После всех манипуляций с архитектурой и обучением закономерно возникает вопрос: как понять, насколько хорошо наша предобученная модель адаптировалась к новым данным? Простой взгляд на итоговую точность не всегда даёт полную картину. Тут нам потребуется целый арсенал методик оценки. Традиционные метрики вроде точности (accuracy), полноты (recall) и точности в узком смысле (precision) — лишь верхушка айсберга. F1-мера, объединяющая precision и recall, может быть информативнее, особенно при несбалансированных классах. А для многоклассовой классификации matrix confusion (матрица ошибок) наглядно показывает, какие классы модель путает между собой.

Важнейший инструмент — кривые обучения. Если валидационная точность стабилизируется, а тренировочная продолжает расти — приветствуйте переобучение. Если обе кривые стабилизировались на низком уровне — модель не достаточно сложна или нужно размораживать больше слоев.

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Визуализируем кривые обучения
plt.figure(figsize=(12, 5))
plt.subplot(1, 2, 1)
plt.plot(history.history['accuracy'], 'b-', label='Training Acc')
plt.plot(history.history['val_accuracy'], 'r-', label='Validation Acc')
plt.title('Accuracy Curves')
plt.xlabel('Эпохи')
plt.ylabel('Точность')
plt.legend()
 
plt.subplot(1, 2, 2)
plt.plot(history.history['loss'], 'b-', label='Training Loss')
plt.plot(history.history['val_loss'], 'r-', label='Validation Loss')
plt.title('Loss Curves')
plt.xlabel('Эпохи')
plt.ylabel('Потери')
plt.legend()
plt.tight_layout()
plt.show()
Тонкий момент в оценке трансферного обучения — анализ активаций скрытых слоёв. Сравнивая распределения активаций на исходном и целевом доменах, можно выявить "мертвые" нейроны или, наоборот, перевозбужденные участки сети. Для этого существуют специальные техники вроде t-SNE или UMAP, позволяющие визуализировать многомерные данные в 2D-пространстве. Метод градиентного подъёма (gradient ascent) позволяет генерировать входные изображения, максимально активирующие определённые нейроны или слои. Это помогает понять, какие именно паттерны научилась распознавать наша адаптированая модель. Для строгой оценки пригодится кросс-валидация. Вместо одного разбиения на тренировочную и валидационную выборки, используем K разбиений, каждый раз обучая модель заново — так получим более надёжную оценку с доверительными интервалами.

Интегральный показатель качества адаптации — способность модели к генерализации на данных из смежных, но не идентичных доменов. Например, если модель обучена на фотографиях животных, сделанных днём, проверьте её на ночных снимках или рисунках тех же животных. Анализ времени адаптации — тоже важный критерий. Хорошо адаптированная модель должна достигать приемлемой точности за относительно небольшое число эпох. Если для достижения приличных результатов требуется 100+ эпох, возможно, выбрана неоптимальная стратегия переноса или базовая архитектура.

И наконец, самая честная но трудоёмкая оценка — A/B тестирование в реальных условиях. Только так можно по-настоящему понять, насколько успешно модель адаптировалась к решению практических задач.

Многозадачное обучение на базе предобученных моделей: архитектурные решения



Многозадачное обучение (Multi-Task Learning, MTL) – это следующий шаг эволюции трансферного обучения. Вместо того чтобы адаптировать предобученную модель для одной конкретной задачи, мы заставляем её работать сразу над несколькими проблемами одновременно. Представьте себе ResNet, который одновременно классифицирует объекты, определяет их положение и сегментирует изображение – это и есть многозадачное обучение в действии. Ключевой инсайт многозадачного обучения: задачи, относящиеся к одному домену, часто используют сходные низкоуровневые признаки. Базовая архитектура многозадачной модели обычно состоит из общего "ствола" (shared backbone) и отдельных "веток" для каждой задачи. Общий ствол – обычно это предобученная сеть, например ResNet50 без верхушки – отвечает за извлечение общих признаков, а специализированные ветви решают конкретные задачи.

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# Пример многозадачной модели в Keras
from tensorflow.keras.applications import ResNet50
from tensorflow.keras.layers import Dense, GlobalAveragePooling2D, Conv2D
from tensorflow.keras.models import Model
 
# Загружаем базовую модель
base_model = ResNet50(weights='imagenet', include_top=False)
base_model.trainable = False
 
# Общий выход базовой модели
shared_features = base_model.output
 
# Ветвь для классификации
classification_branch = GlobalAveragePooling2D()(shared_features)
classification_branch = Dense(256, activation='relu')(classification_branch)
classification_output = Dense(10, activation='softmax', name='classification')(classification_branch)
 
# Ветвь для регрессии (например, определение координат)
regression_branch = GlobalAveragePooling2D()(shared_features)
regression_branch = Dense(256, activation='relu')(regression_branch)
regression_output = Dense(4, name='regression')(regression_branch)
 
# Создаем модель с двумя выходами
model = Model(inputs=base_model.input, outputs=[classification_output, regression_output])
 
# Компилируем модель с разными функциями потерь
model.compile(
    optimizer='adam',
    loss={
        'classification': 'categorical_crossentropy',
        'regression': 'mean_squared_error'
    },
    metrics={
        'classification': 'accuracy',
        'regression': 'mae'
    }
)
Преимущества такой архитектуры очевидны: экономия вычеслительных ресурсов (один общий экстрактор признаков вместо нескольких), улучшение генерализации (модель учится более общим представлениям, полезным для разных задач) и частично решается проблема нехватки данных для отдельных задач.

Интересный архитектурный паттерн – "cross-stitch networks", где информация между задачами обмениваeтся на разных уровнях сети через специальные слои, которые учатся оптимально комбинировать признаки. Такие архитектуры особенно эффективны, когда задачи имеют разный уровень сложности или не полностью коррелированы. Для задач с разными типами входных данных применяются так называемые "multi-modal" архитектуры. Например, при создании системы автономного вождения, где на вход подаются и изоброжения, и данные лидара, и текстовая информация. В таких случаях каждая модальность обрабатывается своим специализированным "энкодером" (часто предобученным), а затем всё сводится в единую многозадачную модель.

Основная проблема многозадачного обучения – балансировка потерь между задачами. Если одна из задач значительно сложнее других или имеет бóльшую функцию потерь, она может доминировать при обучении. Решение – взвешивание потерь разных задач, что в Keras реализуется через параметр loss_weights при компиляции модели. Трудно переоценить значение архитектурных решений для успешного многозадачного обучения – они определяют, насколько эффективно модель сможет использовать общие представления и при этом адаптироватся к специфике каждой задачи.

Продвинутые стратегии и оптимизация



Аугментация данных - секретное оружие при недостатке обучающих примеров. Для трансферного обучения особенно ценны аугментации, моделирующие реальные вариации, с которыми столкнётся модель. Например, для медицинских снимков - вариации контраста и яркости, для распознавания объектов на улице - эмуляция разных погодных условий.

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Продвинутая аугментация с библиотекой albumentations
import albumentations as A
import cv2
 
transform = A.Compose([
    A.RandomBrightnessContrast(p=0.8),
    A.RandomGamma(p=0.8),
    A.CLAHE(p=0.5),  # Улучшение локального контраста
    A.HueSaturationValue(hue_shift_limit=10, sat_shift_limit=15, 
                        val_shift_limit=10, p=0.7),
    A.ShiftScaleRotate(shift_limit=0.15, scale_limit=0.15, 
                      rotate_limit=25, p=0.8),
    A.CoarseDropout(max_holes=8, max_height=8, max_width=8, p=0.5)
])
 
# Применение трансформации
augmented = transform(image=image)['image']
Когда имеем дело с микроскопическими датасетами (десятки или сотни примеров), стоит обратить внимание на технику "progressive resizing". Начинаем обучение на изображениях маленького размера, постепенно увеличивая разрешение. Это ускоряет сходимость и повышает стабильность.

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

Ещё одна хитрость – адаптивное замораживание/размораживание слоев. Вместо того чтобы решать заранее, сколько слоев заморозить, можно мониторить градиенты в разных частях сети и динамически регулировать, какие части дообучать:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Псевдокод для адаптивного размораживания
def adaptive_unfreezing(model, threshold=0.01):
    # Сначала все слои заморожены
    for layer in model.layers:
        layer.trainable = False
    
    # Обучаем новую "головy" несколько эпох
    train_head_only(model, epochs=5)
    
    # Мониторим градиенты и размораживаем слои с большими градиентами
    gradients = compute_gradients(model)
    for layer, grad in zip(reversed(model.layers), gradients):
        if np.mean(np.abs(grad)) > threshold:
            layer.trainable = True
    
    # Продолжаем обучение с адаптированными слоями
    continue_training(model, learning_rate=1e-5)
В малоресурсных средах (например, на мобильных устройствах) критична оптимизация размера и скорости модели. Тут целый арсенал техник: квантизация весов (переход от float32 к int8), дистилляция знаний (обучение компактной модели имитировать большую), прунинг неинформативных связей.
Дистилляция знаний особенно хорошо сочетается с трансферным обучением – сначала адаптируем большую предобученную модель к нашей задаче, потом "дистиллируем" её знания в компактную сеть:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Упрощенный пример дистилляции
# Предполагается, что teacher_model уже адаптирован к нашей задаче
def distill_knowledge(teacher_model, student_model, X_train, temperature=5.0):
    # Получаем "мягкие метки" от учителя
    soft_targets = teacher_model.predict(X_train)
    soft_targets = softmax(soft_targets / temperature)
    
    # Обучаем ученика имитировать учителя
    student_model.compile(
        optimizer=Adam(1e-4),
        loss=lambda y_true, y_pred: kullback_leibler_divergence(
            soft_targets, softmax(y_pred / temperature)
        )
    )
    student_model.fit(X_train, soft_targets, epochs=10)
Эффективность любой продвинутой стратегии сильно зависит от конкретной задачи и доступных ресурсов. Важно не увлекаться сложными оптимизациями, если базовый подход даёт приемлемые результаты – совершенствовать стоит только то, что действительно является узким местом.
Говоря о малоресурсных средах, нельзя обойти стороной технику "смешанной точности" (mixed precision training). Эта технология задействует операции с более низкой точностью (обычно float16 вместо float32) для ускорения вычислений при сохранении точности модели. В TensorFlow это реализуется просто:

Python
1
2
3
4
# Включаем смешанную точность
from tensorflow.keras.mixed_precision import experimental as mixed_precision
policy = mixed_precision.Policy('mixed_float16')
mixed_precision.set_global_policy(policy)
Для некоторых архитектур это может ускорить обучение в 2-3 раза с минимальной потерей точности. На современных GPU с тензорными ядрами эффект еще заметнее.
Другой важный аспект – поиск оптимальной архитектуры. Вместо экспериментов методом проб и ошибок можно использовать алгоритмы автоматического поиска архитектур (NAS, Neural Architecture Search):

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import kerastuner as kt
 
def build_model(hp):
    # Выбираем базовую модель из нескольких вариантов
    base_model_choice = hp.Choice('base_model', 
                              ['resnet50', 'mobilenetv2', 'efficientnetb0'])
    if base_model_choice == 'resnet50':
        base_model = ResNet50(weights='imagenet', include_top=False)
    elif base_model_choice == 'mobilenetv2':
        base_model = MobileNetV2(weights='imagenet', include_top=False)
    else:
        base_model = EfficientNetB0(weights='imagenet', include_top=False)
    
    # Настраиваем, сколько слоев размораживать
    trainable_ratio = hp.Float('trainable_ratio', 0.0, 0.5, step=0.1)
    num_layers = len(base_model.layers)
    for layer in base_model.layers[int(trainable_ratio * num_layers):]:
        layer.trainable = False
    
    # Строим верхушку модели
    x = base_model.output
    x = GlobalAveragePooling2D()(x)
    x = Dense(hp.Int('units', 64, 256, step=64),
           activation=hp.Choice('activation', ['relu', 'selu']))(x)
    output = Dense(num_classes, activation='softmax')(x)
    
    model = Model(inputs=base_model.input, outputs=output)
    model.compile(
        optimizer=Adam(hp.Float('learning_rate', 1e-5, 1e-3, sampling='log')),
        loss='categorical_crossentropy',
        metrics=['accuracy']
    )
    return model
 
tuner = kt.RandomSearch(
    build_model,
    objective='val_accuracy',
    max_trials=10
)
 
tuner.search(train_generator, validation_data=val_generator, epochs=3)
Эта техника особенно полезна, когда неясно, какая предобученная модель лучше подойдет для вашей задачи, какую часть сети стоит размораживать и какие гиперпараметры использовать.
Ещё один мощный приём – "ансамблирование" нескольких моделей трансферного обучения. Вместо выбора одной архитектуры, используем несколько разных (например, ResNet50, InceptionV3, EfficientNetB0) и комбинируем их предсказания:

Техники преодоления проблемы забывания предыдущих знаний



Когда нейронная сеть осваивает новые задачи, она часто платит высокую цену — забывает то, чему научилась ранее. Это явление получило название "катастрофического забывания" (catastrophic forgetting). Представьте, что вы часами настраивали свою VGG16 для идеального распознавания пород собак, а потом решили дообучить её на кошек — и вдруг обнаружили, что собак она теперь путает. Нейросети, как капризные студенты, легко вытесняют старые знания новыми.

Как же бороться с этой проблемой? Первый подход — регуляризация с эластичной передачей весов (Elastic Weight Consolidation, EWC). Суть в том, что важные для старой задачи веса защищаются от больших изменений путём добавления штрафа к функции потерь. Модель запоминает, какие параметры критичны для прошлых умений, и осторожнее их модифицирует.

Python
1
2
3
4
5
6
7
8
9
10
11
# Упрощенная реализация EWC в Keras
def ewc_loss(original_model, current_model, fisher_matrix, lambda_const=0.1):
    # Рассчитываем квадрат разницы между старыми и новыми весами
    penalties = []
    for orig_layer, curr_layer, fisher in zip(original_model.layers, 
                                           current_model.layers, 
                                           fisher_matrix):
        if hasattr(orig_layer, 'kernel'):
            penalty = lambda_const * fisher * K.square(orig_layer.kernel - curr_layer.kernel)
            penalties.append(K.sum(penalty))
    return sum(penalties)
Второй подход — прогрессивные нейронные сети. Вместо изменения существующих весов, мы фиксируем предыдущую модель и добавляем новые слои для новой задачи, при этом создавая боковые соединения со старыми слоями. Старые знания остаются нетронутыми, а новые строятся "рядом".

Техника "experience replay" позаимствована из обучения с подкреплением. Мы сохраняем небольшое количество данных из прошлых задач и периодически повторяем обучение на них, освежая память модели. Это как повторение пройденного материала перед новой темой.

"Learning without Forgetting" (LwF) — остроумная техника, избегающая необходимости хранить старые данные. Перед обучением на новых данных мы получаем выходы предобученной модели для этих же данных и используем их как "мягкие метки", которые модель должна продолжать воспроизводить даже после дообучения.

Метод "Synaptic Intelligence" отслеживает важность каждого веса на протяжении всего обучения, накапливая её как "интеллектуальный капитал" синапса. Веса с высоким капиталом защищаются сильнее при последующих изменениях.

На практике часто используют гибридные подходы. Например, комбинируют EWC с эпизодической памятью или LwF с прогрессивными сетями. Какой бы метод вы ни выбрали, помните: борьба с забыванием — это баланс между стабильностью и пластичностью нейронной сети, между сохранением прошлого и адаптацией к будущему.

Квантизация и прунинг: сохранение эффективности при уменьшении размера модели



После всех наших оптимизаций и тонких настроек мы получили модель, которая прекрасно справляется с задачей. Но тут приходит разработчик мобильного приложения и говорит: "Ваша модель весит 100 мегабайт, а нам нужно 10". Или DevOps-инженер: "Инференс слишком медленный, сервера не справляются с нагрузкой". Что делать? На помощь приходят две мощные техники — квантизация и прунинг.

Квантизация — это уменьшение количества бит, используемых для представления весов. Обычно веса хранятся в 32-битном формате float32, но исследования показывают, что во многих случаях достаточно 8 или даже 4 бит без существенной потери точности. Применение квантизации к предобученной модели может сократить её размер в 2-4 раза и значительно ускорить инференс, особенно на специализированых чипах.

Python
1
2
3
4
5
6
7
8
9
10
11
# Квантизация модели в TensorFlow
import tensorflow as tf
 
# Конвертируем float32 модель в int8
converter = tf.lite.TFLiteConverter.from_keras_model(model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
quantized_model = converter.convert()
 
# Сохраняем квантизированную модель
with open('quantized_model.tflite', 'wb') as f:
    f.write(quantized_model)
А как насчет прунинга? Представте, что мы смотрим на нейроную сеть и видим, что некоторые связи практически не влияют на результат — их веса близки к нулю. Зачем хранить и вычислять то, что по сути бесполезно? Прунинг (от англ. pruning — обрезка) как раз занимается удалением таких связей. В результате получается более разряженная модель, которая может быть сжата специальными алгоритмами. Один из подходов — постепенное прореживание во время обучения:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import tensorflow_model_optimization as tfmot
 
# Определяем расписание прунинга — от 0% до 80% в первые 5 эпох
pruning_schedule = tfmot.sparsity.keras.PolynomialDecay(
    initial_sparsity=0.0, 
    final_sparsity=0.80,
    begin_step=0,
    end_step=5 * steps_per_epoch
)
 
# Оборачиваем модель для прунинга
pruned_model = tfmot.sparsity.keras.prune_low_magnitude(
    model, pruning_schedule=pruning_schedule
)
 
# Компилируем и обучаем как обычно
pruned_model.compile(...)
pruned_model.fit(...)
 
# Убираем побочные прунинг-слои после обучения
final_model = tfmot.sparsity.keras.strip_pruning(pruned_model)
Особенно интерессно сочетание квантизации и прунинга с трансферным обучением. Поскольку предобученные модели и так содержат полезные признаки, мы можем быть более агрессивными в прореживании верхних слоёв, сохраняя при этом приемлемую точность. А квантизация работает особенно хорошо, когда распределение активаций известно и стабильно, что часто верно для предобученых моделей.

Но не всё так просто. Существует компромис между компрессией модели и ее точностью. Каждый проект требует своего баланса. Для некоторых критических приложений, например в медицине, даже небольшая потеря точности недопустима. В таких случаях лучше использовать менее агрессивные настройки или обратиться к техникам знаниевой дистилляции. Важно правильно оценивать эффект квантизации и прунинга. Недостаточно смотреть только на общую точность — нужно анализировать, как изменяется поведение модели на отдельных классах или сложных примерах. Иногда квантизация может непропорционально ухудшать результаты для редких классов или граничных случаев.

Исследования и будущие направления развития технологии



Самоконтролируемое предобучение (self-supervised pretraining) стремительно набирает обороты. Вместо обучения на размеченых данных, модели учатся предсказывать части входных данных на основе других частей тех же данных. Например, BERT предсказывает маскированные слова в предложении, а в компьютерном зрении модели учатся восстанавливать скрытые фрагменты изображений или предсказывать взаиную ориентацию частей. Такой подход позволяет использовать для предобучения гигантские массивы неразмеченных данных.

Кросс-модальное трансферное обучение – еще одна захватывающая область. Модели вроде CLIP (Contrastive Language-Image Pretraining) обучаются одновременно на текстах и изображениях, формируя единое семантическое пространство для обеих модальностей. Это открывает возможности для нулевого обучения (zero-shot learning) – распознавания объектов, которые модель никогда не видела во время обучения, только по текстовому описанию.

Федеративное обучение предлагает совершенно иной подход к переносу знаний — вместо передачи данных на центральный сервер, модели обучаются локально на устройствах пользователей, а затем происходит обмен только обновлениями весов. Это решает проблемы конфиденциальности и позволяет использовать данные, которые иначе были бы недоступны.

Мета-обучение ("learning to learn") идет еще дальше — модели обучаются самому процесу адаптации к новым задачам. Такие системы способны буквально за несколько примеров подстроится под новую, ранее невиданную задачу.

Мультимодальное трансферное обучение: совмещение текстовых и визуальных представлений



Мультимодальное обучение — это как если бы ваш мозг одновременно получал информацию через глаза и уши, создавая целостное понимание. Нейросети тоже могут работать с разными типами данных одновременно, но до недавнего времени это было скорее исключением, чем правилом. Большинство моделей были узкоспециализированными — либо для текста, либо для изображений, либо для звука. Сегодня ситуация меняется со скоростью света.

Суть мультимодального трансферного обучения заключается в создании единого семантического пространства, где могут сосуществовать и взаимодействовать представления из разных модальностей. Например, фраза "золотой ретривер" и фотография этой собаки должны оказаться близко друг к другу в этом пространстве. Архитектуры для решения этой задачи обычно состоят из нескольких энкодеров — отдельно для текста и изображений — и механизма, который сводит их выходы в единое представление. Ключевой момент здесь — правильно спроектировать функцию потерь, заставляющую модель сближать семантически похожие элементы из разных модальностей.

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Упрощенный пример мультимодальной модели
# Загружаем предобученные модели для изображений и текста
image_model = ResNet50(weights='imagenet', include_top=False)
text_model = BertModel.from_pretrained('bert-base-uncased')
 
# Замораживаем базовые модели
for layer in image_model.layers:
    layer.trainable = False
    
# Создаем верхние слои для проецирования в общее пространство
image_features = image_model.output
image_features = GlobalAveragePooling2D()(image_features)
image_embedding = Dense(512, activation=None)(image_features)
 
text_features = text_model.output
text_embedding = Dense(512, activation=None)(text_features)
 
# Нормализация эмбеддингов для косинусного расстояния
image_embedding = Lambda(lambda x: tf.nn.l2_normalize(x, axis=1))(image_embedding)
text_embedding = Lambda(lambda x: tf.nn.l2_normalize(x, axis=1))(text_embedding)
CLIP (Contrastive Language-Image Pretraining) от OpenAI — яркий пример такого подхода. Эта модель обучается сопоставлять изображения с описывающими их текстами, максимизируя косинусную схожесть между ними. Что поразительно — модель способна выполнять классификацию изображений даже для классов, которых не было в обучающих данных, опираясь только на их текстовые описания.

Такой подход открывает дверь в мир "zero-shot" и "few-shot learning" — способности модели распознавать объекты по минимальному количеству примеров или даже без них. Представьте: вы описываете словами новый вид фрукта, а модель потом способна находить его на фотографиях, никогда не видя его раньше!

Мультимодальное трансферное обучение особенно ценно в таких областях, как поиск изображений по текстовому запросу, генерация подписей к фотографиям, создание текстовых описаний для видео и даже в системах виртуальных ассистентов, которым необходимо понимать смысл как визуального, так и текстового контента.

Самоконтролируемое и полуавтоматическое трансферное обучение: новые парадигмы



Если традиционное трансферное обучение — это переезд с чемоданами накопленого опыта, то самоконтролируемое (self-supervised) трансферное обучение — скорее самостоятельное изучение местности без проводника. Суть подхода проста и гениальна: модель сама генерирует обучающие сигналы из неразмеченных данных, формулируя "псевдозадачи". Представьте, что вы зарываете часть изображения и просите модель восстановить скрытый фрагмент или поворачиваете картинку и предлагаете угадать угол поворота. Никакой ручной разметки не требуется — данные сами становятся своей разметкой! SimCLR, BYOL и MoCo — пионеры этого направления — доказали, что предобучение без учителя может давать признаки, по качеству не уступающие получаемым при обучении с учителем.

Python
1
2
3
4
5
6
7
8
9
10
11
# Пример простой самоконтролируемой задачи
def create_rotated_images(image):
# Создаем повернутые версии одного изображения
rotations = [0, 90, 180, 270]
X_rot = []
y_rot = []  # Метки - углы поворота
for i, angle in enumerate(rotations):
    rotated_img = rotate(image, angle)
    X_rot.append(rotated_img)
    y_rot.append(i)  # Используем индекс угла как метку
return np.array(X_rot), np.array(y_rot)
Полуавтоматическое (semi-supervised) трансферное обучение — еще один прорыв, позволяющий использовать огромные массивы неразмеченных данных вместе с небольшим количеством размеченных примеров. Алгоритмы вроде FixMatch комбинируют технику псевдо-разметки (когда модель сама присваивает метки неразмеченным примерам, в которых она "уверена") с сильной аугментацией данных.

Эти подходы особенно ценны, когда размеченные данные дороги или труднодоступны. В медицине, например, получение экспертной разметки снимков может стоить тысячи долларов, а собрать неразмеченные данные относительно просто.

Исследования показывают, что самоконтролируемое предобучение на одном домене может дать удивително хороший перенос знаний в другой. Модели, обученные предсказывать следующее слово в тексте, отлично справляются с распознаванием эмоций; сети, восстанавливающие цвет черно-белых фотографий, оказываются полезными для сегментации медицинских изображений.

Проблема компиляции Python + TensorFlow + Keras
Всем доброго здоровья. Возникла такая проблема. Не получается скрипт с модулями TensorFlow и Keras...

Дедуктивное обучение или Обучение по прецедентам (плюсы и минусы)
Привет, друзья! Как вы смотрите на то, чтобы обсудить вопрос о преимуществах и недостатках 2...

Обучение модели нейронной сети(обучение с подкреплением)
у меня есть код для реализации обучения модели с помощью алгоритма DDPG, но проблема в том что при...

Keras - классификация текста - оверфиттинг, и как улучшить модель
Я делаю нейронную сеть для классификации текста на русском языке по этим примерам - ...

Что лучше выбрать новичку для криволинейной регрессии: tensorflow, sckit, theano, keras?
Здравствуйте, мне нужно с помощью машинного обучения решить задачу регрессии. Мне понадобится...

Keras tensorflow классификация 10-и объектов
Добрый день. Не могу понять почему так происходит. Примерно один код изменяется незначительно при...

Keras BatchNormalization
Добрый день. во время экспериментов с нейронными сетями решил использовать слой BatchNormalization....

Keras tensorflow классификация 10-и объектов
Добрый день. Как после обучения определить какой выходной персептрон к какому объекту принадлежит?...

Keras нейросеть mnist распознавание с картинки Error when checking input: expected dense_1_input to have 2 dimensions
Добрый вечер. Есть обученная нейросеть по mnist-цифрам, сохранённая в файл. Теперь пытаюсь...

Keras. Как превратить изображение в входной вектор для функции prediction?
Создал нейросеть, которая должна классифицировать того, кто на изображении: кот или собака. from...

Ошибка при создании слоя в keras
Здравствуйте, я изучаю библиотеку keras по примерам в данном примере:...

Нейросети. Keras. Автоенкодер для передачи данных
Есть у меня поделка где я с помощью математики пытаюсь хранить данные в сжатии с потерями. Хочу...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 0
Комментарии
 
Новые блоги и статьи
CQRS (Command Query Responsibility Segregation) на Java
Javaican 12.05.2025
CQRS — Command Query Responsibility Segregation, или разделение ответственности команд и запросов. Суть этого архитектурного паттерна проста: операции чтения данных (запросы) отделяются от операций. . .
Шаблоны и приёмы реализации DDD на C#
stackOverflow 12.05.2025
Когда я впервые погрузился в мир Domain-Driven Design, мне показалось, что это очередная модная методология, которая скоро канет в лету. Однако годы практики убедили меня в обратном. DDD — не просто. . .
Исследование рантаймов контейнеров Docker, containerd и rkt
Mr. Docker 11.05.2025
Когда мы говорим о контейнерных рантаймах, мы обсуждаем программные компоненты, отвечающие за исполнение контейнеризованных приложений. Это тот слой, который берет образ контейнера и превращает его в. . .
Micronaut и GraalVM - будущее микросервисов на Java?
Javaican 11.05.2025
Облачные вычисления безжалостно обнажили ахиллесову пяту Java — прожорливость к ресурсам и медлительный старт приложений. Традиционные фреймворки, годами радовавшие корпоративных разработчиков своей. . .
Инфраструктура как код на C#
stackOverflow 11.05.2025
IaC — это управление и развертывание инфраструктуры через машиночитаемые файлы определений, а не через физическую настройку оборудования или интерактивные инструменты. Представьте: все ваши серверы,. . .
Инъекция зависимостей в ASP.NET Core - Практический подход
UnmanagedCoder 11.05.2025
Инъекция зависимостей (Dependency Injection, DI) — это техника программирования, которая кардинально меняет подход к управлению зависимостями в приложениях. Представьте модульный дом, где каждая. . .
Битва за скорость: может ли Java догнать Rust и C++?
Javaican 11.05.2025
Java, с её мантрой "напиши один раз, запускай где угодно", десятилетиями остаётся в тени своих "быстрых" собратьев, когда речь заходит о сырой вычислительной мощи. Rust и C++ традиционно занимают. . .
Упрощение разработки облачной инфраструктуры с Golang
golander 11.05.2025
Причины популярности Go в облачной инфраструктуре просты и одновременно глубоки. Прежде всего — поразительная конкурентность, реализованная через горутины, которые дешевле традиционных потоков в. . .
Создание конвейеров данных ETL с помощью Pandas
AI_Generated 10.05.2025
Помню свой первый опыт работы с большим датасетом — это была катастрофа из неотформатированных CSV-файлов, странных значений NULL и дубликатов, от которых ехала крыша. Тогда я потратил три дня на. . .
C++ и OpenCV - Гайд по продвинутому компьютерному зрению
bytestream 10.05.2025
Компьютерное зрение — одна из тех технологий, которые буквально меняют мир на наших глазах. Если оглянуться на несколько лет назад, то сложно представить, что алгоритмы смогут не просто распознавать. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru