|
|
|
import numpy as np |
|
import random |
|
import re |
|
from bs4 import BeautifulSoup |
|
import requests |
|
import wikipedia |
|
|
|
class NeuralNet: |
|
def __init__(self, input_size, hidden_size, output_size): |
|
self.Wxh = np.random.randn(hidden_size, input_size) * 0.01 |
|
self.Whh = np.random.randn(hidden_size, hidden_size) * 0.01 |
|
self.Why = np.random.randn(output_size, hidden_size) * 0.01 |
|
self.bh = np.zeros((hidden_size, 1)) |
|
self.by = np.zeros((output_size, 1)) |
|
|
|
def forward(self, inputs, h_prev): |
|
h = np.tanh(np.dot(self.Wxh, inputs) + np.dot(self.Whh, h_prev) + self.bh) |
|
y = np.dot(self.Why, h) + self.by |
|
return y, h |
|
|
|
def train(self, X, Y, learning_rate=0.01, epochs=1000): |
|
for epoch in range(epochs): |
|
loss = 0 |
|
h_prev = np.zeros((self.Whh.shape[0], 1)) |
|
|
|
for i in range(len(X)): |
|
x = np.array(X[i]).reshape(-1, 1) |
|
y_true = np.array(Y[i]).reshape(-1, 1) |
|
|
|
|
|
y_pred, h_prev = self.forward(x, h_prev) |
|
|
|
|
|
loss += np.sum((y_pred - y_true) ** 2) |
|
|
|
|
|
dy = y_pred - y_true |
|
dWhy = np.dot(dy, h_prev.T) |
|
dby = dy |
|
|
|
dh = np.dot(self.Why.T, dy) |
|
dh_raw = (1 - h_prev ** 2) * dh |
|
|
|
dWxh = np.dot(dh_raw, x.T) |
|
dWhh = np.dot(dh_raw, h_prev.T) |
|
dbh = dh_raw |
|
|
|
|
|
self.Wxh -= learning_rate * dWxh |
|
self.Whh -= learning_rate * dWhh |
|
self.Why -= learning_rate * dWhy |
|
self.bh -= learning_rate * dbh |
|
self.by -= learning_rate * dby |
|
|
|
if epoch % 100 == 0: |
|
print(f'Epoch {epoch}, Loss: {loss}') |
|
|
|
class MaestroAssistant: |
|
def __init__(self): |
|
self.wake_word = "эй маэстро" |
|
self.vocab = {} |
|
self.intents = { |
|
'greet': ['привет', 'здравствуй', 'добрый день'], |
|
'search': ['найди', 'поищи', 'что такое', 'кто такой'], |
|
'joke': ['расскажи шутку', 'пошути', 'анекдот'], |
|
'time': ['который час', 'сколько времени', 'время'] |
|
} |
|
self.responses = { |
|
'greet': ['Приветствую!', 'Здравствуйте!', 'Привет! Чем могу помочь?'], |
|
'search': ['Ищу информацию...', 'Сейчас найду...', 'Одну секунду...'], |
|
'joke': ['Я не умею шутить, но могу найти сайт для генерации шуток!', 'Я не создавать шутки, но могу найти сайт с ними, просто скажите: Эй Маэстро, найди сайт со смешными шутками!'], |
|
'default': ['Не понял вас', 'Повторите, пожалуйста', 'Я вас не понял, скажите повторно!'] |
|
} |
|
|
|
|
|
self.init_vocab() |
|
input_size = len(self.vocab) |
|
hidden_size = 64 |
|
output_size = len(self.intents) |
|
self.nn = NeuralNet(input_size, hidden_size, output_size) |
|
|
|
|
|
self.train() |
|
|
|
def init_vocab(self): |
|
|
|
words = set() |
|
for intent in self.intents.values(): |
|
for phrase in intent: |
|
words.update(phrase.split()) |
|
self.vocab = {word: i for i, word in enumerate(words)} |
|
|
|
def text_to_vector(self, text): |
|
|
|
vector = np.zeros(len(self.vocab)) |
|
for word in text.split(): |
|
if word in self.vocab: |
|
vector[self.vocab[word]] += 1 |
|
return vector |
|
|
|
def train(self): |
|
|
|
X = [] |
|
y = [] |
|
for i, (intent, phrases) in enumerate(self.intents.items()): |
|
for phrase in phrases: |
|
X.append(self.text_to_vector(phrase)) |
|
y_vec = np.zeros(len(self.intents)) |
|
y_vec[i] = 1 |
|
y.append(y_vec) |
|
|
|
|
|
X = np.array(X) |
|
y = np.array(y) |
|
|
|
|
|
self.nn.train(X, y, epochs=1000, learning_rate=0.01) |
|
|
|
def predict_intent(self, text): |
|
|
|
vector = self.text_to_vector(text) |
|
output, _ = self.nn.forward(vector.reshape(-1, 1), np.zeros((self.nn.Whh.shape[0], 1))) |
|
intent_idx = np.argmax(output) |
|
return list(self.intents.keys())[intent_idx] |
|
|
|
def handle_command(self, command): |
|
|
|
if not command.startswith(self.wake_word): |
|
return None |
|
|
|
command = command[len(self.wake_word):].strip() |
|
intent = self.predict_intent(command) |
|
|
|
if intent == 'greet': |
|
return random.choice(self.responses['greet']) |
|
elif intent == 'joke': |
|
return random.choice(self.responses['joke']) |
|
elif intent == 'search': |
|
query = re.sub(r'(найди|поищи|что такое|кто такой)', '', command).strip() |
|
return self.search(query) |
|
else: |
|
return random.choice(self.responses['default']) |
|
|
|
def search(self, query): |
|
|
|
try: |
|
wikipedia.set_lang('ru') |
|
result = wikipedia.summary(query, sentences=2) |
|
return f"Вот что я нашел в Википедии: {result}" |
|
except: |
|
pass |
|
|
|
|
|
try: |
|
url = f"https://www.google.com/search?q={query}" |
|
headers = {'User-Agent': 'Mozilla/5.0'} |
|
response = requests.get(url, headers=headers) |
|
soup = BeautifulSoup(response.text, 'html.parser') |
|
|
|
|
|
result = soup.find('div', class_='BNeawe').text |
|
return f"Вот что я нашел: {result[:200]}..." |
|
except Exception as e: |
|
return f"Не удалось найти информацию: {str(e)}" |