32 #ifndef SHARK_MODELS_LINEARMODEL_H 33 #define SHARK_MODELS_LINEARMODEL_H 56 template <
class InputType = RealVector,
class ActivationFunction = LinearNeuron>
59 blas::vector<typename InputType::value_type, typename InputType::device_type>,
60 blas::vector<typename InputType::value_type, typename InputType::device_type>
63 typedef blas::vector<typename InputType::value_type, typename InputType::device_type> VectorType;
64 typedef blas::matrix<typename InputType::value_type, blas::row_major, typename InputType::device_type> MatrixType;
71 ActivationFunction m_activation;
80 if(std::is_base_of<blas::dense_tag, typename InputType::storage_type::storage_tag>::value){
86 : m_inputShape(inputs)
87 , m_outputShape(outputs)
88 , m_matrix(outputs.numElements(),inputs.numElements(),0.0)
89 , m_offset(
offset?outputs.numElements():0,0.0){
91 if(std::is_base_of<blas::dense_tag, typename InputType::storage_type::storage_tag>::value){
98 {
return "LinearModel"; }
102 : m_inputShape(matrix.size2())
103 , m_outputShape(matrix.size1())
107 if(std::is_base_of<blas::dense_tag, typename InputType::storage_type::storage_tag>::value){
114 return m_offset.size() != 0;
123 return m_outputShape;
128 return to_vector(m_matrix) | m_offset;
135 noalias(to_vector(m_matrix)) = subrange(newParameters, 0, numInputs * numOutputs);
136 noalias(m_offset) = subrange(newParameters, numInputs * numOutputs, newParameters.size());
141 return m_matrix.size1()*m_matrix.size2()+m_offset.size();
184 return boost::shared_ptr<State>(
new typename ActivationFunction::State());
190 void eval(BatchInputType
const& inputs, BatchOutputType& outputs)
const{
191 outputs.resize(inputs.size1(),m_matrix.size1());
193 noalias(outputs) = inputs % trans(m_matrix);
195 noalias(outputs)+=repeat(m_offset,inputs.size1());
197 m_activation.evalInPlace(outputs);
201 output.resize(m_matrix.size1());
203 noalias(output) = m_matrix % input;
205 noalias(output) += m_offset;
207 m_activation.evalInPlace(output);
210 void eval(BatchInputType
const& inputs, BatchOutputType& outputs,
State& state)
const{
211 outputs.resize(inputs.size1(),m_matrix.size1());
213 noalias(outputs) = inputs % trans(m_matrix);
215 noalias(outputs)+=repeat(m_offset,inputs.size1());
217 m_activation.evalInPlace(outputs, state.
toState<
typename ActivationFunction::State>());
222 BatchInputType
const& patterns,
223 BatchOutputType
const& outputs,
224 BatchOutputType
const& coefficients,
226 ParameterVectorType& gradient
228 SIZE_CHECK(coefficients.size2()==m_matrix.size1());
229 SIZE_CHECK(coefficients.size1()==patterns.size1());
235 std::size_t matrixParams = numInputs*numOutputs;
237 auto weightGradient = blas::to_matrix(subrange(gradient,0,matrixParams), numOutputs,numInputs);
239 BatchOutputType delta = coefficients;
240 m_activation.multiplyDerivative(outputs,delta, state.
toState<
typename ActivationFunction::State>());
242 noalias(weightGradient) = trans(delta) % patterns;
245 noalias(subrange(gradient, matrixParams, matrixParams + numOutputs)) = sum_rows(delta);
250 BatchInputType
const & patterns,
251 BatchOutputType
const& outputs,
252 BatchOutputType
const & coefficients,
254 MatrixType& derivative
256 SIZE_CHECK(coefficients.size2() == m_matrix.size1());
257 SIZE_CHECK(coefficients.size1() == patterns.size1());
260 BatchOutputType delta = coefficients;
261 m_activation.multiplyDerivative(outputs,delta, state.
toState<
typename ActivationFunction::State>());
263 derivative.resize(patterns.size1(),patterns.size2());
264 noalias(derivative) = delta % m_matrix;
268 BatchInputType
const & patterns,
269 BatchOutputType
const& outputs,
270 BatchOutputType
const & coefficients,
272 ParameterVectorType& parameterDerivative,
273 MatrixType& inputDerivative
275 SIZE_CHECK(coefficients.size2()==m_matrix.size1());
276 SIZE_CHECK(coefficients.size1()==patterns.size1());
282 BatchOutputType delta = coefficients;
283 m_activation.multiplyDerivative(outputs,delta, state.
toState<
typename ActivationFunction::State>());
286 inputDerivative.resize(patterns.size1(),numInputs);
287 noalias(inputDerivative) = delta % m_matrix;
291 parameterDerivative.clear();
292 std::size_t matrixParams = numInputs*numOutputs;
293 auto weightGradient = blas::to_matrix(subrange(parameterDerivative,0,matrixParams), numOutputs,numInputs);
294 auto offsetGradient = subrange(parameterDerivative,matrixParams,parameterDerivative.size());
297 noalias(weightGradient) = trans(delta) % patterns;
299 noalias(offsetGradient) = sum_rows(delta);
307 archive >> m_inputShape;
308 archive >> m_outputShape;
314 archive << m_inputShape;
315 archive << m_outputShape;
330 template<
class VectorType = RealVector>
337 {
return "LinearClassifier"; }