TensorFlow Simple Example

[English translation may be some day]

Представляю вашему вниманию простейший пример работы с фреймворком для работы с Deep Learning – TensorFlow. В этом примере мы научим нейросеть определять положительние, отрицательные числа и ноль. Установку TensorFlow и CUDA я поручаю вам, эта задачка действительно не из легких)

Для решения задач классификации используются классификаторы. TensorFlow имеет несколько готовых высокоуровневых классификаторов, которые требуют минимальной конфигурации для работы. Сначала мы потренируем DNNClassifier с помощью датасета с положительными, отрицательными числами и нулем – с корректными “лейблами”. На человеческом уровне датасет представляет из себя набор чисел с результатом классификации (лейблами):

10 – положительное
-22 – отрицательное
0 – ноль
42 – положительное
… другие числа с классификацией

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

import tensorflow
import itertools
import random

from time import time

class ClassifiedNumber:
    
    __number = 0
    __classifiedAs = 3
    
    def __init__(self, number):
        
        self.__number = number
        
        if number == 0:
            self.__classifiedAs = 0 # zero
            
        elif number > 0:
            self.__classifiedAs = 1 # positive
            
        elif number < 0:
            self.__classifiedAs = 2 # negative
            
    def number(self):
        return self.__number
    
    def classifiedAs(self):
        return self.__classifiedAs
    
def classifiedAsString(classifiedAs):
    
    if classifiedAs == 0:
        return "Zero"
    
    elif classifiedAs == 1:
        return "Positive"
    
    elif classifiedAs == 2:
        return "Negative"

def trainDatasetFunction():
    
    trainNumbers = []
    trainNumberLabels = []
    
    for i in range(-1000, 1001):    
        number = ClassifiedNumber(i)
        trainNumbers.append(number.number())
        trainNumberLabels.append(number.classifiedAs())
    
    return ( {"number" : trainNumbers } , trainNumberLabels )

def inputDatasetFunction():
    
    global randomSeed
    random.seed(randomSeed) # to get same result
    
    numbers = []
    
    for i in range(0, 4):
        numbers.append(random.randint(-9999999, 9999999))
    
    return {"number" : numbers }
    
def main():
    
    print("TensorFlow Positive-Negative-Zero numbers classifier test by demensdeum 2017 (demensdeum@gmail.com)")
    
    maximalClassesCount = len(set(trainDatasetFunction()[1])) + 1
    
    numberFeature = tensorflow.feature_column.numeric_column("number")
    classifier = tensorflow.estimator.DNNClassifier(feature_columns = [numberFeature], hidden_units = [10, 20, 10], n_classes = maximalClassesCount)
    generator = classifier.train(input_fn = trainDatasetFunction, steps = 1000).predict(input_fn = inputDatasetFunction)
    
    inputDataset = inputDatasetFunction()
    
    results = list(itertools.islice(generator, len(inputDatasetFunction()["number"])))
    
    i = 0
    for result in results:
        print("number: %d classified as %s" % (inputDataset["number"][i], classifiedAsString(result["class_ids"][0])))
        i += 1

randomSeed = time()

main()

Все начинается в методе main(), мы задаем числовую колонку с которой будет работать классификатор – tensorflow.feature_column.numeric_column(“number”) далее задаются параметры классификатора. Описывать текущие аргументы инициализации бесполезно, так как API меняется каждый день, и обязательно нужно смотреть документацию именно установленной версии TensorFlow, не полагаться на устаревшие мануалы.

Далее запускается обучение с указанием на функцию которая возвращает датасет из чисел от -1000 до 1000 (trainDatasetFunction), с правильной классификацией этих чисел по признаку положительного, отрицательного либо нуля. Следом подаем на вход числа которых не было в обучающем датасете – случайные от -9999999 до 9999999 (inputDatasetFunction) для их классификации.

В финале запускаем итерации по количеству входных данных (itertools.islice) печатаем результат, запускаем и удивляемся:

number: 4063470 classified as Positive
number: 6006715 classified as Positive
number: -5367127 classified as Negative
number: -7834276 classified as Negative

iT’S ALIVE

Честно говоря я до сих пор немного удивлен что классификатор *понимает* даже те числа которым я его не обучал. Надеюсь в дальнейшем я разберусь более подробно с темой машинного обучения и будут еще туториалы.

GitHub:
https://github.com/demensdeum/MachineLearning

Ссылки:
https://developers.googleblog.com/2017/09/introducing-tensorflow-datasets.html
https://www.tensorflow.org/versions/master/api_docs/python/tf/estimator/DNNClassifier