← Назад к вопросам
Что такое computational graph?
1.7 Middle🔥 111 комментариев
#Глубокое обучение#Машинное обучение
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Computational Graph (Граф вычислений)
Computational Graph — это граф, в котором вершины представляют операции (сложение, умножение, функции активации и т.д.), а рёбра — тензоры (данные), передаваемые между операциями. Это абстракция, которая позволяет фреймворкам вроде TensorFlow и PyTorch эффективно вычислять градиенты и оптимизировать вычисления.
В компьютерной графике говорят, что «computational graph — это мост между математикой и кодом».
Структура Computational Graph
Пример простого графика
Для функции: z = (x + y) * w
x y
\ /
+ <- сумма
|
[x+y]
|
* <- умножение
/ \
[x+y] w
|
z <- результат
Реализация в коде
import torch
import numpy as np
# PyTorch автоматически создаёт computational graph
x = torch.tensor(2.0, requires_grad=True) # requires_grad=True отслеживает операции
y = torch.tensor(3.0, requires_grad=True)
w = torch.tensor(4.0, requires_grad=True)
# Каждая операция добавляется в граф
z = (x + y) * w
print(f'z = {z}') # 20.0
print(f'z.grad_fn = {z.grad_fn}') # MulBackward0 — говорит, как был получен z
# Просмотр полного графика
print(z.grad_fn) # Показывает операцию умножения
print(z.grad_fn.next_functions) # Показывает зависимые операции
Dynamic vs Static Graphs
Dynamic Computational Graph (PyTorch)
Граф создаётся на лету во время выполнения кода.
import torch
def compute_dynamic(x):
y = x * 2
if x > 1:
z = y + 1
else:
z = y - 1
return z
x = torch.tensor(2.0, requires_grad=True)
result = compute_dynamic(x)
print(f'Result: {result}')
result.backward() # Автоматический дифференцирование
print(f'Gradient: {x.grad}')
Преимущества:
- Гибкость: можно использовать Python условия и циклы
- Легче дебажить (стандартные точки останова работают)
- Подходит для сложных архитектур
Static Computational Graph (TensorFlow 1.x)
Граф определяется один раз, затем выполняется множество раз.
# TensorFlow 1.x (старый стиль)
import tensorflow as tf
# Определить граф
x = tf.placeholder(tf.float32)
y = tf.placeholder(tf.float32)
z = (x + y) * 2
# Создать сессию для выполнения
with tf.Session() as sess:
result = sess.run(z, feed_dict={x: 2.0, y: 3.0})
print(f'Result: {result}')
Преимущества:
- Оптимизация: TensorFlow может анализировать граф перед выполнением
- Распараллеливание и развёртывание на несколько устройств
Обратное распространение (Backpropagation)
Как работает обратное распространение
- Forward Pass — вычисляются все операции от входа к выходу, создаётся граф
- Backward Pass — вычисляются градиенты от выхода к входу
Пример с вычислением градиентов
import torch
# Forward pass
x = torch.tensor(2.0, requires_grad=True)
y = torch.tensor(3.0, requires_grad=True)
# z = (x^2 + y^3) * 2
z = (x**2 + y**3) * 2
print(f'z = {z}') # z = (4 + 27) * 2 = 62
# Backward pass
z.backward()
# Градиенты
print(f'dz/dx = {x.grad}') # dz/dx = 2 * 2 * 2 = 8
print(f'dz/dy = {y.grad}') # dz/dy = 3 * y^2 * 2 = 3 * 9 * 2 = 54
Расчёт вручную для проверки
z = (x^2 + y^3) * 2
dz/dx = d/dx[(x^2 + y^3) * 2]
= 2 * d/dx[x^2 + y^3]
= 2 * (2x)
= 4x
= 4 * 2 = 8 ✓
dz/dy = d/dy[(x^2 + y^3) * 2]
= 2 * d/dy[x^2 + y^3]
= 2 * (3y^2)
= 6y^2
= 6 * 9 = 54 ✓
Computational Graph в нейросетях
Простой пример с нейросетью
import torch
import torch.nn as nn
# Определить простую нейросеть
class SimpleNet(nn.Module):
def __init__(self):
super().__init__()
self.fc1 = nn.Linear(2, 4) # Входной слой 2 -> скрытый 4
self.fc2 = nn.Linear(4, 1) # Скрытый 4 -> выход 1
def forward(self, x):
x = torch.relu(self.fc1(x)) # ReLU активация
x = self.fc2(x) # Линейный выход
return x
model = SimpleNet()
# Входные данные
X = torch.tensor([[1.0, 2.0], [3.0, 4.0]])
y_true = torch.tensor([[1.0], [0.0]])
# Forward pass
y_pred = model(X)
print(f'Predictions: {y_pred}')
# Вычислить потерю
loss = nn.MSELoss()(y_pred, y_true)
print(f'Loss: {loss}')
# Backward pass: вычислить градиенты для всех параметров
loss.backward()
# Просмотреть градиенты
for name, param in model.named_parameters():
if param.grad is not None:
print(f'{name} gradient shape: {param.grad.shape}')
Визуализация Computational Graph
TensorBoard
import torch
from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter('runs/experiment1')
# Модель
model = SimpleNet()
X = torch.randn(1, 2)
# Записать граф в TensorBoard
writer.add_graph(model, X)
writer.close()
# Запустить: tensorboard --logdir=runs
Visualize в PyTorch
import torch
from torchviz import make_dot
x = torch.randn(1, 2, requires_grad=True)
model = SimpleNet()
y = model(x)
# Создать визуализацию графика
vis_graph = make_dot(y, params=dict(model.named_parameters()))
vis_graph.render('computational_graph', format='png')
Оптимизация Графика
Fреймворки оптимизируют computational graph:
# Умная оптимизация автоматическая, но можно контролировать
# 1. Отключить отслеживание градиентов (когда не нужны)
with torch.no_grad():
predictions = model(X) # Не создаёт граф
# 2. Использовать eval() для отключения dropout и batch norm
model.eval()
# 3. Отсоединить от графика
x = torch.randn(3, requires_grad=True)
y = x ** 2
z = y.detach() # z больше не зависит от x
# 4. Использовать gradient checkpointing для больших моделей
# (экономит память, но медленнее)
Практическая работа с графиком
Полный пример обучения
import torch
import torch.nn as nn
import torch.optim as optim
# Модель
model = SimpleNet()
loss_fn = nn.MSELoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)
# Данные
X = torch.randn(10, 2)
y = torch.randn(10, 1)
# Обучение
for epoch in range(100):
# Forward pass: граф создаётся
y_pred = model(X)
loss = loss_fn(y_pred, y)
# Backward pass: вычисляются градиенты
optimizer.zero_grad() # Очистить старые градиенты
loss.backward() # Обратное распространение
# Обновить параметры
optimizer.step()
if (epoch + 1) % 20 == 0:
print(f'Epoch {epoch+1}, Loss: {loss.item():.4f}')
print('Training complete!')
Ключевые концепции
Операции в графике
# Все эти операции добавляются в граф
a = torch.tensor([1.0], requires_grad=True)
b = torch.tensor([2.0], requires_grad=True)
c = a + b # AddBackward
d = c * a # MulBackward
e = torch.sin(d) # SinBackward
f = e ** 2 # PowBackward
# Граф: a --|--|
# +--> c --> d --> e --> f
# b --|--| | |
# a--|------
Листья графика
x = torch.tensor([2.0], requires_grad=True)
y = x ** 2
z = y * 3
print(f'x.is_leaf: {x.is_leaf}') # True (входная переменная)
print(f'y.is_leaf: {y.is_leaf}') # False (результат операции)
print(f'z.is_leaf: {z.is_leaf}') # False (результат операции)
print(f'z.grad_fn: {z.grad_fn}') # MulBackward
print(f'x.grad_fn: {x.grad_fn}') # None
Выводы
- Computational Graph — это основа автоматического дифференцирования
- Forward Pass создаёт граф, Backward Pass вычисляет градиенты
- PyTorch использует динамические графики (удобнее для разработки)
- TensorFlow (новая версия) тоже использует eager execution по умолчанию
- Понимание графика помогает дебажить и оптимизировать нейросети
- Используй
requires_grad=True,backward()иno_grad()для контроля