Skip to content

Commit 0254a43

Browse files
committed
feat/solvers: reintroduce solvers for Layers
1 parent 9f0f128 commit 0254a43

File tree

12 files changed

+644
-619
lines changed

12 files changed

+644
-619
lines changed

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ collenchyma-nn = { version = "0.3.2", default-features = false }
2020

2121
log = "0.3.2"
2222
rand = "0.3.0"
23+
num = "0.1"
2324

2425
clippy = { version = "0.0.41", optional = true }
2526

examples/benchmarks.rs

-4
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,6 @@ fn bench_alexnet() {
157157
let func = || {
158158
let forward_time = timeit_loops!(1, {
159159
{
160-
let loss = &mut 0f32;
161160
let inp = SharedTensor::<f32>::new(backend.device(), &vec![128, 3, 224, 224]).unwrap();
162161

163162
let inp_lock = Arc::new(RwLock::new(inp));
@@ -239,7 +238,6 @@ fn bench_overfeat() {
239238
let func = || {
240239
let forward_time = timeit_loops!(1, {
241240
{
242-
let loss = &mut 0f32;
243241
let inp = SharedTensor::<f32>::new(backend.device(), &vec![128, 3, 231, 231]).unwrap();
244242

245243
let inp_lock = Arc::new(RwLock::new(inp));
@@ -324,7 +322,6 @@ fn bench_vgg_a() {
324322
cfg.add_layer(LayerConfig::new("conv8/relu", LayerType::ReLU));
325323
let pool5_layer_cfg = PoolingConfig { mode: PoolingMode::Max, filter_shape: vec![2], stride: vec![2], padding: vec![0] };
326324
cfg.add_layer(LayerConfig::new("pool5", pool5_layer_cfg));
327-
let fc1_layer_cfg = LinearConfig { output_size: 4096 };
328325
cfg.add_layer(LayerConfig::new("fc1", LinearConfig { output_size: 4096 }));
329326
cfg.add_layer(LayerConfig::new("fc2", LinearConfig { output_size: 4096 }));
330327
cfg.add_layer(LayerConfig::new("fc3", LinearConfig { output_size: 1000 }));
@@ -337,7 +334,6 @@ fn bench_vgg_a() {
337334
let func = || {
338335
let forward_time = timeit_loops!(1, {
339336
{
340-
let loss = &mut 0f32;
341337
let inp = SharedTensor::<f32>::new(backend.device(), &vec![64, 3, 224, 224]).unwrap();
342338

343339
let inp_lock = Arc::new(RwLock::new(inp));

src/layer.rs

+25-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Provides the generics and interfaces for the specific [Layers][layers].
22
//! [layers]: ../layers/index.html
3-
use co::{IBackend, ITensorDesc, SharedTensor};
3+
use co::prelude::*;
44
use layers::*;
55
use weight::WeightConfig;
66
use util::{ArcLock, native_backend, LayerOps};
@@ -610,13 +610,12 @@ impl<B: IBackend + LayerOps<f32> + 'static> Layer<B> {
610610
/// [3]: ../solver/enum.LRPolicy.html
611611
pub fn update_weights<SolverB: IBackend + ::util::SolverOps<f32>>(&mut self, backend: &SolverB) {
612612
let mut shared_a = ::util::native_scalar(-1f32);
613-
let _ = shared_a.add_device(backend.device());
614-
shared_a.sync(backend.device()).unwrap();
613+
let _ = shared_a.add_device(IBackend::device(backend));
614+
shared_a.sync(IBackend::device(backend)).unwrap();
615615
for (weight_gradient, weight_data) in self.learnable_weights_gradients().iter().zip(&mut self.learnable_weights_data()) {
616-
weight_gradient.write().unwrap().sync(backend.device()).unwrap();
617-
weight_data.write().unwrap().sync(backend.device()).unwrap();
616+
weight_gradient.write().unwrap().sync(IBackend::device(backend)).unwrap();
617+
weight_data.write().unwrap().sync(IBackend::device(backend)).unwrap();
618618
backend.axpy_plain(&shared_a, &weight_gradient.read().unwrap(), &mut weight_data.write().unwrap()).unwrap();
619-
// weight_blob.write().unwrap().apply_diff(backend) // TODO: solver
620619
}
621620
}
622621

@@ -690,6 +689,17 @@ impl<B: IBackend + LayerOps<f32> + 'static> Layer<B> {
690689
if let Some(gradients) = self.worker.learnable_weights_gradients() { gradients }
691690
else { self.weights_gradient.clone() }
692691
}
692+
693+
/// Returns the learning rate for all the learnable weights in the layer.
694+
///
695+
/// If the layer is a container layer it will return all learning rates of the
696+
/// layers inside it.
697+
pub fn learnable_weights_lr(&self) -> Vec<Option<f32>> {
698+
if let Some(lr) = self.worker.learnable_weights_lr() { lr }
699+
// else { self.weights_lr.clone() }
700+
else {
701+
self.learnable_weights_data().iter().map(|_| Some(1f32)).collect::<Vec<_>>() }
702+
}
693703
}
694704

695705
/// A Layer in a [Neural Network][1] that can handle forward and backward of a computation step.
@@ -1024,6 +1034,14 @@ pub trait ILayer<B: IBackend> : ComputeOutput<f32, B> + ComputeInputGradient<f32
10241034
fn learnable_weights_gradients(&self) -> Option<Vec<ArcLock<SharedTensor<f32>>>> {
10251035
None
10261036
}
1037+
1038+
/// Return the learning rates for the learnable weights inside the layer.
1039+
///
1040+
/// This should only be overridden by container layers,
1041+
/// where the weights are not easily exposable.
1042+
fn learnable_weights_lr(&self) -> Option<Vec<Option<f32>>> {
1043+
None
1044+
}
10271045
}
10281046

10291047
/// A Layer that can compute the output for a given input.
@@ -1061,7 +1079,7 @@ pub trait ComputeParametersGradient<T, B: IBackend> {
10611079

10621080
impl<B: IBackend> fmt::Debug for ILayer<B> {
10631081
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1064-
write!(f, "({}, {})", "foo", "bar")
1082+
write!(f, "({})", "ILayer")
10651083
}
10661084
}
10671085

src/lib.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -124,15 +124,16 @@ extern crate timeit;
124124
#[macro_use]
125125
extern crate log;
126126
extern crate rand;
127+
extern crate num;
127128
extern crate collenchyma as co;
128129
extern crate collenchyma_blas as coblas;
129130
extern crate collenchyma_nn as conn;
130131
pub mod layer;
131132
pub mod layers;
132-
// #[cfg(feature="cuda")]
133-
// pub mod solver;
134-
// #[cfg(feature="cuda")]
135-
// pub mod solvers;
133+
#[cfg(feature="cuda")]
134+
pub mod solver;
135+
#[cfg(feature="cuda")]
136+
pub mod solvers;
136137
pub mod weight;
137138

138139
pub mod util;

0 commit comments

Comments
 (0)