class TensorStream::Train::Optimizer
Base class for an optimizer This is a straight up port from the python version
Attributes
name[R]
Public Class Methods
new(name:, use_locking:)
click to toggle source
# File lib/tensor_stream/train/optimizer.rb, line 10 def initialize(name:, use_locking:) @name = name @use_locking = use_locking raise TensorStream::ValueError, "Must specify the optimizer name" unless @name @slots = {} @non_slots = {} end
Public Instance Methods
apply_gradients(grads_and_vars, global_step: nil, name: nil)
click to toggle source
Apply gradients to variables. This is the second part of minimize(). It returns an Operation
that applies gradients.
# File lib/tensor_stream/train/optimizer.rb, line 27 def apply_gradients(grads_and_vars, global_step: nil, name: nil) varlist = grads_and_vars.map { |_grad, var| var } create_slots(varlist) TensorStream.name_scope(name, default: @name) do prepare apply_ops = grads_and_vars.map { |grad, var| TensorStream.name_scope("update_" + var.op.name) do apply_dense(grad, var) end } if global_step.nil? finish(apply_ops, name) else TensorStream.control_dependencies([finish(apply_ops, "update")]) do global_step.assign_add(1) end end end end
compute_gradients(loss, var_list: nil, grad_loss: nil)
click to toggle source
Compute gradients of loss for the variables in var_list.
This is the first part of minimize(). It returns a list of (gradient, variable) pairs where “gradient” is the gradient for “variable”.
# File lib/tensor_stream/train/optimizer.rb, line 52 def compute_gradients(loss, var_list: nil, grad_loss: nil) trainable_vars = if var_list raise "var_list must be an array" unless var_list.is_a?(Array) var_list.each_with_index { |var, index| raise "var #{index} not a Variable" unless var.is_a?(Variable) } var_list else loss.graph.get_collection(TensorStream::GraphKeys::TRAINABLE_VARIABLES) end all_grads = grad_loss || TensorStream.gradients(loss, trainable_vars) trainable_vars.each_with_index.collect do |var, index| [all_grads[index], var] end end
get_slot(var, name)
click to toggle source
# File lib/tensor_stream/train/optimizer.rb, line 68 def get_slot(var, name) named_slots = @slots.fetch(name, nil) return nil if named_slots.nil? named_slots.fetch(var_key(var), nil) end
get_slot_names()
click to toggle source
# File lib/tensor_stream/train/optimizer.rb, line 75 def get_slot_names @slots.keys.sort end
minimize(loss, var_list: nil, grad_loss: nil, global_step: nil, name: nil)
click to toggle source
# File lib/tensor_stream/train/optimizer.rb, line 19 def minimize(loss, var_list: nil, grad_loss: nil, global_step: nil, name: nil) grads_and_vars = compute_gradients(loss, var_list: var_list, grad_loss: grad_loss) apply_gradients(grads_and_vars, global_step: global_step, name: name) end
Protected Instance Methods
apply_dense(_grad, _var)
click to toggle source
# File lib/tensor_stream/train/optimizer.rb, line 93 def apply_dense(_grad, _var) raise TensorStream::NotImplementedError, "not implemented" end
call_if_callable(param)
click to toggle source
# File lib/tensor_stream/train/optimizer.rb, line 137 def call_if_callable(param) param.is_a?(Proc) ? param.call : param end
create_non_slot_variable(initial_value, name, colocate_with)
click to toggle source
# File lib/tensor_stream/train/optimizer.rb, line 141 def create_non_slot_variable(initial_value, name, colocate_with) graph = colocate_with.graph key = [name, graph] v = @non_slots.fetch(key, nil) if v.nil? v = TensorStream.variable(initial_value, name: name, trainable: false) @non_slots[key] = v end v end
create_slots(var_list)
click to toggle source
# File lib/tensor_stream/train/optimizer.rb, line 85 def create_slots(var_list) # no implementation end
finish(update_ops, name_scope)
click to toggle source
# File lib/tensor_stream/train/optimizer.rb, line 81 def finish(update_ops, name_scope) TensorStream.group(update_ops, name: name_scope) end
get_non_slot_variable(name, graph: nil)
click to toggle source
# File lib/tensor_stream/train/optimizer.rb, line 132 def get_non_slot_variable(name, graph: nil) non_slot = @non_slots.fetch([name, graph], nil) non_slot end
get_or_make_slot_with_initializer(var, initializer, shape, dtype, slot_name, op_name)
click to toggle source
Find or create a slot for a variable, using an Initializer
.
# File lib/tensor_stream/train/optimizer.rb, line 155 def get_or_make_slot_with_initializer(var, initializer, shape, dtype, slot_name, op_name) named_slots = slot_dict(slot_name) unless named_slots.key?(var_key(var)) new_slot_variable = create_slot_with_initializer(var, initializer, shape, dtype, op_name) named_slots[var_key(var)] = new_slot_variable end named_slots[var_key(var)] end
prepare()
click to toggle source
# File lib/tensor_stream/train/optimizer.rb, line 89 def prepare # no implementation end
slot_dict(slot_name)
click to toggle source
Returns a dict for caching slots created under the given name.
Args: slot_name string Name for the slot
Returns: A dict that maps primary 'Variable' objects to the slot created
# File lib/tensor_stream/train/optimizer.rb, line 119 def slot_dict(slot_name) named_slots = @slots.fetch(slot_name, nil) if named_slots.nil? named_slots = {} @slots[slot_name] = named_slots end named_slots end
var_key(var)
click to toggle source
# File lib/tensor_stream/train/optimizer.rb, line 128 def var_key(var) [var.op.graph, var.op.name] end
zeros_slot(var, slot_name, op_name)
click to toggle source
Find or create a slot initialized with 0.0.
Args:
var: Variable - A Variable object slot_name: string - Name for the slot op_name: string - Name to use when scoping the Variable that needs to be created
# File lib/tensor_stream/train/optimizer.rb, line 104 def zeros_slot(var, slot_name, op_name) named_slots = slot_dict(slot_name) unless named_slots.key?(var_key(var)) named_slots[var_key(var)] = create_zeros_slot(var, op_name) end named_slots[var_key(var)] end