Skip to main content
added 2 characters in body; edited title
Source Link
toolic
  • 15.9k
  • 6
  • 29
  • 217

neural Neural network that determines the gender of a word

I wrote a neural network in pythonPython using pytorch,PyTorch which determines the gender of a word in Russian. As a training set: a file containing a word and a number from 0 to 2 (0-masculine,1 1- femininefeminine and 2-neuter). I'd like to improve and simplify this code as I'm not too familiar with pytorchPyTorch technology yet, I'd. I'd appreciate any advice.

linkLink to the list of words (need to use utf-8) https://inf2086.ru/files/russian_nouns.txt

neural network that determines the gender of a word

I wrote a neural network in python using pytorch, which determines the gender of a word in Russian. As a training set: a file containing a word and a number from 0 to 2 (0-masculine,1- feminine and 2-neuter). I'd like to improve and simplify this code as I'm not too familiar with pytorch technology yet, I'd appreciate any advice.

link to the list of words (need to use utf-8) https://inf2086.ru/files/russian_nouns.txt

Neural network that determines the gender of a word

I wrote a neural network in Python using PyTorch which determines the gender of a word in Russian. As a training set: a file containing a word and a number from 0 to 2 (0-masculine, 1-feminine and 2-neuter). I'd like to improve and simplify this code as I'm not too familiar with PyTorch technology yet. I'd appreciate any advice.

Link to the list of words (need to use utf-8) https://inf2086.ru/files/russian_nouns.txt

deleted 1 character in body
Source Link
user269440
user269440

link to the list of words (need to use utf-8) https://inf2086.ru/files/russian_nouns.txt.

link to the list of words (need to use utf-8) https://inf2086.ru/files/russian_nouns.txt

Source Link
user269440
user269440

neural network that determines the gender of a word

I wrote a neural network in python using pytorch, which determines the gender of a word in Russian. As a training set: a file containing a word and a number from 0 to 2 (0-masculine,1- feminine and 2-neuter). I'd like to improve and simplify this code as I'm not too familiar with pytorch technology yet, I'd appreciate any advice.

import torch
import random
class DenseLayer:
    def __init__(self, activation, input_size, output_size):
        self.weights = torch.normal(mean = 0.0, std = 2.0/(input_size + output_size)**0.5, size=(input_size, output_size))
        self.weights.requires_grad_()

        self.bias = torch.zeros(output_size)
        self.bias.requires_grad_()

        self.activation = activation

    def __call__(self, inputs):
        return self.activation(torch.tensordot(inputs, self.weights, dims=1) + self.bias)
  
    def update_weights(self, learning_rate):
        with torch.no_grad(): ## отключает построение графа вычислений
            self.weights -= self.weights.grad * learning_rate
            self.weights.grad = None
            
            self.bias -= self.bias.grad * learning_rate
            self.bias.grad = None

def relu(x):
    return (x > 0) * x

def softmax(x):
    return x.exp() / x.exp().sum(-1)

def cross_entropy(x, y, BATCH_SIZE = 50):
    N = BATCH_SIZE
    loss = -1 * (1 / N) * (torch.tensordot(y, x.log()))
    return loss


class Network:
    def __init__(self, input_size, layer_sizes, output_size):
        self.layers = []
        prev_size = input_size
        for size in layer_sizes:
            self.layers.append(DenseLayer(relu, prev_size, size))
            prev_size = size

        self.layers.append(DenseLayer(softmax, prev_size, output_size))
    
    def __call__(self, inputs):
        for layer in self.layers:
            inputs = layer(inputs)
        return inputs
    
    def train(self, words, classes, learning_rate):
        train_words = self(words[0]).clone()
        train_words = torch.reshape(train_words, (1, 3,))
        for i in range(1, len(words)):
            word = self(words[i])
            word = torch.reshape(word, (1, 3,))
            train_words = torch.cat((train_words, word))
        loss = cross_entropy(train_words, classes)
        loss.backward()
        for layer in self.layers:
            layer.update_weights(learning_rate)
        return loss.item()

def load_dictionary(filename):
    words, classes = [], []
    with open(filename, encoding='utf8') as f:
        for line in f.readlines():
            line = line.split()
            words.append(word_onehot(line[0]))
            classes.append(cls_onehot(line[1]))
    return words, classes

def clean_word(word):
    punctuation = '.,;:"!?""_-'
    word = word.lower()
    word = word.strip(punctuation)
    return word

def word_onehot(word, ALPHABET = 'абвгдеёжзийклмнопрстуфхцчшщъыьэюя', MAX_LEN = 20):
    ALPHABET_SIZE = len(ALPHABET)
    word = clean_word(word)
    word_encoded = torch.zeros(MAX_LEN * ALPHABET_SIZE)
    for i in range(len(word)):
        if i > MAX_LEN-1: break
        word_encoded[i * ALPHABET_SIZE + ALPHABET.index(word[len(word) - 1 - i])] = 1.
    return word_encoded

def cls_onehot(cls, size = 3):
    cls = int(cls)
    cls_encoded = [0.] * size
    cls_encoded[cls] = 1.
    return cls_encoded

def gen_batch(words,classes, BATCH_SIZE = 50):
    index = random.randint(0, len(classes) - BATCH_SIZE-1)
    words = words[index:index + BATCH_SIZE]
    classes = classes[index:index + BATCH_SIZE]
    return words, classes

def main():
    words, classes = load_dictionary('russian_nouns.txt')
    classes = torch.tensor(classes)
    MAX_LEN= 20
    nn = Network(33 * MAX_LEN, [20, 15, 10, 15, 20], 3)
    for epoch in range(5001):
        words_batch, classes_batch = gen_batch(words, classes)
        loss = nn.train(words_batch, classes_batch, 0.01)
        if epoch % 500 == 0:
            print(f'completed {epoch//50}%', 'loss = ', loss)
    print('== Training completed ==')
    torch.save(nn, 'bumba.txt')
    while True:
        word = input()
        ind = nn(word_onehot(word)).tolist().index(max(nn(word_onehot(word)).tolist()))
        if ind == 0: print("Мужской род")
        if ind == 1: print("Женский род")
        if ind == 2: print("Средний род")

if __name__ == "__main__":
    main()

link to the list of words (need to use utf-8) https://inf2086.ru/files/russian_nouns.txt.