Основная цель этого блога — построить простую модель линейной классификации в ruby с использованием архитектуры Tensorflow. Основными компонентами тензорного потока, необходимыми для построения и тестирования модели, являются Operation, Placeholder, Variable и Session. Эти компоненты написаны как рубиновые классы. Начнем с класса Operation.
class Operation attr_accessor :input_nodes, :output, :input def initialize(*input_nodes) @input_nodes = input_nodes end def compute raise "Should be implemented" end end
Класс Operation
формирует основу всех вычислений в тензорном потоке. Метод compute
выполняет необходимые вычисления. Давайте создадим несколько классов, которые наследуют класс Operation
, и мы будем использовать сигмоид в качестве функции активации для модели.
require Matrix class Add < Operation def initialize(*nodes) @input_nodes=nodes end def compute(x,y) return x.element(0,0) + y end end class Matmul < Operation def initialize(*nodes) @input_nodes=nodes end def compute(x,y) return Matrix[x] * Matrix[y].transpose end end class Sigmoid < Operation def initialize(*nodes) @input_nodes=nodes end def compute(z) 1/(1+Math.exp(-z)) end end
Загрузите библиотеку Matrix в начале для вычисления матрицы. Теперь, когда мы создали базовые классы операций, мы перейдем к другим компонентам.
class Placeholder attr_accessor :value, :output end class Variable attr_accessor :value, :output def initialize(value) @value = value end end
Класс Placeholder
содержит объекты, которые являются входными или выходными данными модели. Эти объекты действуют как константы, и их значения не меняются во время сеанса. Variable
содержит объекты, значения которых являются либо весами, либо смещением, заданным для модели. В реальной модели тензорного потока эти значения обновляются с помощью оптимизатора (например, AdamOptimizer, Stocastic Gradient Descent и т. д.). Мы не будем обновлять какое-либо значение в нашем подходе. Мы фиксируем значение веса и смещения как [1,1] и -5 соответственно. Теперь мы определим класс сеанса.
class Session def run(operation,feed_dict={}) nodes = traverse_postorder(operation) nodes.each do |node| if node.is_a? Placeholder node.output = feed_dict[node.object_id] elsif node.is_a? Variable node.output = node.value else node.input = node.input_nodes.map { |input| input.output } node.output = node.compute(*node.input) end end operation.output end def traverse_postorder(operation) node_operators = [] recurse(operation,node_operators) end def recurse(node,node_operators) if node.is_a?(Operation) node.input_nodes.each do |input_node| recurse(input_node,node_operators) end end node_operators << node end end
Класс Session
позаботится обо всех исполнениях. Сначала он преобразует набор операций в постфиксный порядок. Затем операции выполняются одна за другой. Поскольку мы создали все необходимые компоненты, давайте приступим к делу.
W = Variable.new([1,1]) #Weight b = Variable.new(-5) #bias x = Placeholder.new() #input y = Matmul.new(W,x) z = Add.new(y,b) a = Sigmoid.new(z) #activation function sess = Session.new()
Посмотрим прогноз для двух крайних точек
result = sess.run(a,feed_dict={x.object_id=>[0,-10]}) puts(result)% 3.059022269256247e-07
Точка (0,-10)
лежит в нижнем левом углу графика, поэтому значение сигмоиды ближе к 0.
result = sess.run(a,feed_dict={x.object_id=>[8,10]}) puts(result)% 0.999997739675702
Для точки (8,10)
, расположенной в правом верхнем углу графика, значение сигмоиды ближе к 1.
Надеюсь, этот пример дает хорошее представление об основных компонентах tensorflow в ruby. Удачного обучения !!!
Спасибо, что нашли время, чтобы прочитать мои статьи. Если вам понравился мой контент и вы хотели бы быть в курсе моих последних сообщений, я был бы признателен, если бы вы могли подписаться на меня на Medium. Ваша поддержка очень много значит и будет мотивировать меня продолжать делиться с вами ценными знаниями и идеями. Спасибо заранее за вашу поддержку!
Первоначально опубликовано на https://ethigeek.com.