Основы методов искусственного интеллекта. Учебно-методическое пособие
.pdfСогласованность дуг (arc consistency) — это техника, используемая в алгоритмах поиска пути, которая позволяет уменьшить количество возможных вариантов для следующего шага путем проверки согласованности между вершинами. Если мы знаем, что какой-то выбранный путь невозможен, то мы можем исключить все пути, которые начинаются или заканчиваются на этом пути.
Пример реализации алгоритма согласованности дуг:
def revise(csp, i, j): revised = False
for x in csp.domain[i]:
if all(not csp.constraints(i, x, j, y) for y in csp.domain[j]): csp.domain[i].remove(x)
revised = True return revised
def arc _ consistency(csp):
queue = [(i, j) for i in range(csp.n _ variables) for j in csp. constraints[i]]
while queue:
i, j = queue.pop(0) if revise(csp, i, j):
if not csp.domain[i]: return False
for k in csp.constraints[i]: if k != j:
queue.append((k, i))
return True
В этом примере мы имеем класс CSP, который содержит информацию о переменных, их доменах и ограничениях, которые должны быть выполнены для каждой пары переменных. Метод constraints возвращает список переменных, которые связаны спеременной i ограничениями.
Метод revise принимает две переменные, i и j, и проверяет, можно ли удалять значения из домена переменной i, чтобы убедиться, что все значения в домене переменной j могут быть использованы для удовлетворения ограничений. Если была произведена ревизия, метод возвращает True, иначе — False.
Функция arc _ consistency выполняет алгоритм согласованности дуг, используя очередь, которая начинается со всех связанных дуг и продолжается до тех пор, пока не будут удалены все ненужные значения доменов переменных. Если на каком-то шаге домен переменной становится пустым, значит, решения нет.
Для использования этого алгоритма необходимо создать объект класса CSP с соответствующими переменными, доменами и ограничениями, а затем вызвать функцию arc _ consistency:
41
class CSP:
def _ _ init _ _(self, variables, domains, constraints): self.variables = variables
self.domains = domains self.constraints = constraints self.n _ variables = len(variables)
variables = [0, 1, 2]
domains = {0: [1, 2, 3], 1: [1, 2], 2: [1, 2, 3]} constraints = {0: [1, 2], 1: [0], 2: [0]}
csp = CSP(variables, domains, constraints) result = arc _ consistency(csp) print(result)
Этот код создает объект CSP с тремя переменными 0, 1 и 2 и соответствующими доменами. Ограничения указываются в виде словаря, где ключи — это переменные, а значения — это связанные переменные. Например, для переменной 0 есть два ограничения со связанными переменными 1 и 2.
После создания объекта CSP вызывается функция arc _ consistency с этим объектом в качестве аргумента. Функция возвращает True, если CSP имеет решение, и False, если CSP не имеет решения.
В этом примере CSP имеет решение, поэтому функция arc _ consistency вернет True. Вот как можно модифицировать код, чтобы вывести список доменов переменных после
выполнения алгоритма согласованности дуг:
class CSP:
def _ _ init _ _(self, variables, domains, constraints): self.variables = variables
self.domains = domains self.constraints = constraints self.n _ variables = len(variables)
variables = [0, 1, 2]
domains = {0: [1, 2, 3], 1: [1, 2], 2: [1, 2, 3]} constraints = {0: [1, 2], 1: [0], 2: [0]}
csp = CSP (variables, domains, constraints) arc _ consistency(csp)
for variable in variables:
print (“Domain of variable”, variable, “:”, domains[variable])
42
Результат выполнения этого кода будет следующим:
Domain of variable 0 : [1, 2, 3]
Domain of variable 1 : [1, 2]
Domain of variable 2 : [1, 2, 3]
Можно заметить, что домены переменных не изменились после выполнения алгоритма согласованности дуг в этом примере. Это произошло потому, что CSP имеет решение и не требует удаления значений из доменов переменных. Если CSP не имело бы решения, некоторые значения в домене переменных могли бы быть удалены.
Эти методы ИИ могут применяться для решения широкого круга задач — от простых головоломок до сложных реальных проблем в таких областях, как медицина, финансы и инженерия. По мере дальнейшего развития технологий ИИ эти методы, вероятно, станут еще более сложными и мощными, позволяя решать задачи более эффективно и результативно.
Вопросыдлясамоконтроля
1.Приведите методы искусственного интеллекта, используемые при решении задач.
2.Что такое алгоритмы поиска, как они используются при решении задач?
3.Что такое представление знаний?
4.Расскажите о методе рассуждения.
5.Расскажите о методе обучения.
6.Что такое проверка вперед?
7.Что такое удовлетворение ограничений?
8.Что такое логические представления знаний?
9.Что такое семантические сети?
10.Что такое контролируемое обучение? Где оно применяется?
Глава7.ПРИМЕНЕНИЕНЕЙРОННЫХСЕТЕЙ
Нейронные сети находят практическое применение в различных областях, включая распознавание изображений и речи, обработку естественного языка, прогностическое моделирование, обнаружение аномалий и многое другое. Вот несколько примеров практического применения нейронных сетей с их реализацией в Python.
Распознавание изображений.
Нейронные сети могут распознавать объекты и паттерны на изображениях. Примером может служить распознавание рукописных цифр из набора данных MNIST.
Реализация кода на языке Python:
from keras.datasets import mnist
from keras.utils import to _ categorical from keras.models import Sequential from keras.layers import Dense
# Загружаем набор данных MNIST
(X _ train, y _ train), (X _ test, y _ test) = mnist.load _ data()
# Предварительная обработка данных
X _ train = X _ train.reshape((60000, 28 * 28)) X _ train = X _ train.astype(‘float32’) / 255
43
X _ test |
= |
X _ test.reshape((10000, 28 * 28)) |
X _ test |
= |
X _ test.astype(‘float32’) / 255 |
y _ train = to _ categorical(y _ train) y _ test = to _ categorical(y _ test)
#Определите модель model = Sequential()
model.add(Dense(512, activation=‘relu’, input _ shape=(28 * 28,))) model.add(Dense(10, activation=‘softmax’))
#Скомпилировать модель
model.compile(optimizer=‘rmsprop’, loss=‘categorical _ crossentropy’, metrics=[‘accuracy’])
# Обучить модель
model.fit(X _ train, y _ train, epochs=5, batch _ size=128)
# Оценить модель
test _ loss, test _ acc = model.evaluate(X _ test, y _ test) print(‘Точность теста:’, test _ acc)
Анализ настроений.
Нейронные сети могут выполнять анализ настроения для определения настроения задан - ного текста. Например, чтобы определить, является ли рецензия на фильм положительной или отрицательной.
Реализация кода на языке Python:
import pandas as pd
from keras.preprocessing.text import Tokenizer
из keras.preprocessing.sequence import pad _ sequences from keras.models import Sequential
from keras.layers import Embedding, Flatten, Dense
# Загружаем набор данных
url = ‘https://raw.githubusercontent.com/krishnaik06/SentimentAnalysis/master/Dataset/Train.csv’
df = pd.read _ csv(url)
# Предварительная обработка данных
tokenizer = Tokenizer(num _ words=10000, lower=True) tokenizer.fit _ on _ texts(df[‘text’])
44
X= tokenizer.texts _ to _ sequences(df[‘text’])
X= pad _ sequences(X, maxlen=100)
y = pd.get _ dummies(df[‘sentiment’]).values
#Определите модель model = Sequential()
model.add(Embedding(10000, 64, input _ length=100)) model.add(Flatten())
model.add(Dense(64, activation=‘relu’)) model.add(Dense(3, activation=‘softmax’))
#Скомпилировать модель
model.compile(optimizer=‘adam’, |
loss=‘categorical _ crossentropy’, |
metrics=[‘accuracy’]) |
|
# Обучить модель
model.fit(X, y, epochs=10, batch _ size=32)
# Оценить модель
test _ loss, test _ acc = model.evaluate(X, y) print (‘Точность теста:’, test _ acc)
Прогнозирование временных рядов.
Нейронные сети можно использовать для прогнозирования временных рядов. Примером может служить прогнозирование цен на акции компании.
Реализация кода на языке Python:
import numpy as np import pandas as pd
from sklearn.preprocessing import MinMaxScaler from keras.models import Sequential
from keras.layers import LSTM, Dense
# Загружаем набор данных
df = pd.read _ csv(‘AAPL.csv’) df = df.sort _ values(‘Date’)
# Предварительная обработка данных data = df[‘Close’].values.reshape(-1, 1)
scaler = MinMaxScaler(feature _ range=(0, 1)) data = scaler.fit _ transform(data)
45
X = [] y = []
for i in range(60, len(data)):
X.append(data[i-60:i, 0]) y.append(data[i, 0])
X, y = np.array(X), np.array(y)
# Разделите данные на обучающий и тестовый наборы train _ size = int(len(X) * 0.8)
X _ train, y _ train = X[:train _ size], y[:train _ size]. X _ test, y _ test = X[train _ size:], y[train _ size:]
# Изменение формы входных данных для соответствия модели LSTM
X _ train |
= np.reshape(X _ train, (X _ train.shape[0], X _ train. |
shape[1], 1)) |
|
1))X _ test = |
np.reshape(X _ test, (X _ test.shape[0], X _ test.shape[1], |
#Определите модель LSTM model = Sequential()
model.add(LSTM(50, return _ sequences=True, input _ shape=(60, 1))) model.add(LSTM(50))
model.add(Dense(1))
#Скомпилировать модель
model.compile(optimizer=‘adam’, loss=‘mean _ squared _ error’)
# Обучить модель
model.fit(X _ train, y _ train, epochs=50, batch _ size=32)
# Оценить модель
test _ loss = model.evaluate(X _ test, y _ test) print(‘Test loss:’, test _ loss)
# Делаем прогнозы
predictions = model.predict(X _ test)
predictions = scaler.inverse _ transform(predictions)
# Вывести результаты на экран import matplotlib.pyplot as plt
plt.plot(y _ test, label=‘Actual’) plt.plot(predictions, label=‘Predicted’) plt.legend()
plt.show()
46
Вэтом примере мы загружаем набор данных о ценах на акции Apple (AAPL.csv), который можно загрузить с различных финансовых источников, таких как Yahoo Finance, Google Finance, Alpha Vantage и т.д.
ВданномслучаефайлAAPL.csv был загружен спомощью функцииpandas.read _ csv() из CSV-файла, который был предварительно загружен с одного из этих источников (рис. 8).
Рис. 8. Датасет AAPL
Рис. 9. Пример визуализации данных с использованием библиотеки Matplotlibe
47
Далее предварительно обрабатываем данные, масштабируя их и разбивая на обучающий и тестовый наборы. Затем изменяем форму входных данных, чтобы они подходили для модели LSTM, определяем модель LSTM с двумя слоями LSTM и плотным слоем, компилируем модель с оптимизатором Adam и средним квадратом ошибки потерь, и обучаем модель в течение 50 эпох. Затем оцениваем модель на тестовом множестве, делаем прогнозы на тестовом множестве и строим график фактических и прогнозируемых цен на акции с помощью библиотеки Python — Matplotlib. Данная библиотека используется для визуализации данных двумерной и трехмерной графикой (рис. 9).
Вопросыдлясамоконтроля
1.Приведите примеры практического применения нейронных сетей.
2.Опишите процесс распознавания изображений.
3.Что такое анализ настроений?
4.Опишите суть использования нейронных сетей для прогнозирования временных рядов.
5.Какие библиотеки Python используются для визуализации данных двумерной и трехмерной графики?
Глава8.НЕЙРОДИНАМИЧЕСКОЕПРОГРАММИРОВАНИЕ
Нейродинамическое программирование (НДП, NDP) — это вычислительный подход к ре-
шению проблем оптимизации. В нем объединены идеи обучения с подкреплением, искусственных нейронных сетей и динамического программирования.
Основная идея NDP заключается в том, чтобы представить проблему оптимизации в виде нейронной сети и обучить ее с помощью алгоритма обучения с подкреплением. Нейронная сеть учится аппроксимировать функцию ценности или функцию политики для проблемы оптимизации. Функция ценности представляет собой ожидаемый доход для каждого состояния проблемы оптимизации, а функция политики сопоставляет каждое состояние с действием.
Алгоритм NDP можно кратко описать следующим образом:
1.Инициализируйте нейронную сеть со случайными весами.
2.Выберите состояния из задачи оптимизации.
3.Используйте нейронную сеть для выбора действия на основе текущего состояния.
4.Выполните выбранное действие и наблюдайте за вознаграждением и следующим состоянием.
5.Обновите веса нейронной сети, используя вознаграждение и следующее состояние.
6.Повторяйте шаги 2–5 в течение фиксированного числа итераций или до сходимости. Алгоритм NDP применяется для решения широкого круга задач оптимизации, включая
управление, составление расписания, маршрутизацию и распределение ресурсов. Вот пример реализации NDP в Python с использованием библиотеки PyTorch:
import torch
import torch.nn as nn import torch.optim as optim
class NDPNet(nn.Module):
def _ _ init _ _ (self, input _ size, output _ size, hidden _ size): super(NDPNet, self). _ _ init _ _ ()
self.fc1 = nn.Linear(input _ size, hidden _ size) self.fc2 = nn.Linear(hidden _ size, hidden _ size)
48
self.fc3 = nn.Linear(hidden _ size, output _ size)
def forward(self, x):
x = torch.relu(self.fc1(x)) x = torch.relu(self.fc2(x)) x = self.fc3(x)
return x
def NDP(env, n _ episodes, n _ steps, gamma, lr):
net = NDPNet(env.observation _ space.shape[0], env.action _ space.n,
64)
optimizer = optim.Adam(net.parameters(), lr=lr)
for episode in range(n _ episodes): state = env.reset()
state = torch.tensor(state, dtype=torch.float32).unsqueeze(0) total _ reward = 0
for step in range(n _ steps):
action = net(state).argmax(dim=1)
next _ state, reward, done, _ = env.step(action.item())
next _ state = torch.tensor(next _ state, dtype=torch. float32).unsqueeze(0)
total _ reward += reward
if done:
target = torch.tensor([reward], dtype=torch.float32) else:
values.detach() target = reward + gamma * net(next _ state).max(dim=1).
q _ values = net(state).gather(dim=1, index=action.
unsqueeze(1))
loss = nn.MSELoss()(q _ values, target.unsqueeze(1))
optimizer.zero _ grad() loss.backward() optimizer.step()
49
state = next _ state if done:
break
reward)) print(“Episode {}: Total reward = {}”.format(episode, total _
return net
Вэтом примере мы определяем класс NDPNet, который представляет нейронную сеть для нашей задачи оптимизации. Нейронная сеть имеет три полностью подключенных слоя
сфункциями активации ReLU. Мы определяем прямой метод, который вычисляет выход нейронной сети, учитывая входные данные.
Затем мы определяем функцию NDP, которая принимает на вход среду, количество эпизодов, количество шагов в каждом эпизоде, коэффициент дисконтирования и скорость обучения. Функция инициализирует нейронную сеть и оптимизатор, а затем запускает алгоритм NDP для заданного количества эпизодов.
Вкаждом эпизоде функция выбирает состояние из окружающей среды, использует нейронную сеть для выбора действия, выполняет выбранное действие, наблюдает за вознаграждением и следующим состоянием. Затем функция использует эти значения для обновления весов нейронной сети с помощью алгоритма NDP.
После обучения нейронной сети мы можем использовать ее для составления прогнозов на новых входных данных. Это можно сделать, вызвав метод forward класса NDPNet с входными данными в качестве входных, а результатом метода будет предсказанный выход нейронной сети.
ВотпримериспользованияфункцииNDPдлярешениязадачиCartPole-v1 изOpenAI Gym:
import gym
env = gym.make(‘CartPole-v1’)
net = NDP(env, n _ episodes=100, n _ steps=200, gamma=0.99, lr=0.001)
В этом примере мы создаем экземпляр среды CartPole-v1, а затем вызываем функцию NDP с этой средой в качестве входных данных и другими гиперпараметрами для алгоритма. Функция возвращает обученную нейронную сеть, которую мы присваиваем переменной net.
Затем мы можем использовать обученную нейронную сеть для прогнозирования на новых входных данных, например, для выбора действий в среде:
state = env.reset() done = False
while not done:
state = torch.tensor(state, dtype=torch.float32).unsqueeze(0) action = net(state).argmax(dim=1)
next _ state, reward, done, _ = env.step(action.item())
состояние = next _ state env.render()
50
