PLearn 0.1
|
00001 // -*- C++ -*- 00002 00003 // PLearn (A C++ Machine Learning Library) 00004 // Copyright (C) 1998 Pascal Vincent 00005 // Copyright (C) 1999-2002 Pascal Vincent, Yoshua Bengio, Rejean Ducharme and University of Montreal 00006 // Copyright (C) 2001-2002 Nicolas Chapados, Ichiro Takeuchi, Jean-Sebastien Senecal 00007 // Copyright (C) 2002 Xiangdong Wang, Christian Dorion 00008 00009 // Redistribution and use in source and binary forms, with or without 00010 // modification, are permitted provided that the following conditions are met: 00011 // 00012 // 1. Redistributions of source code must retain the above copyright 00013 // notice, this list of conditions and the following disclaimer. 00014 // 00015 // 2. Redistributions in binary form must reproduce the above copyright 00016 // notice, this list of conditions and the following disclaimer in the 00017 // documentation and/or other materials provided with the distribution. 00018 // 00019 // 3. The name of the authors may not be used to endorse or promote 00020 // products derived from this software without specific prior written 00021 // permission. 00022 // 00023 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 00024 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00025 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 00026 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00027 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00028 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00029 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00030 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00031 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00032 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00033 // 00034 // This file is part of the PLearn library. For more information on the PLearn 00035 // library, go to the PLearn Web site at www.plearn.org 00036 00037 00038 /* ******************************************************* 00039 * $Id: AffineTransformVariable.cc 8770 2008-04-08 17:20:13Z tihocan $ 00040 * This file is part of the PLearn library. 00041 ******************************************************* */ 00042 00043 #include "AffineTransformVariable.h" 00044 00045 namespace PLearn { 00046 using namespace std; 00047 00048 00049 PLEARN_IMPLEMENT_OBJECT( 00050 AffineTransformVariable, 00051 "Affine transformation of a vector variable.", 00052 "The first input is the vector variable.\n" 00053 "The second input is the matrix of biases (on the first row) and\n" 00054 "weights (in other rows).\n" 00055 "If the first input vector is a row vector, then the result is a\n" 00056 "row vector as well. If it is a column vector, then the result is\n" 00057 "also a column vector. If it is a scalar, then the result is a\n" 00058 "column vector as well, unless the option 'force_row_vec' is set\n" 00059 "to true." 00060 ); 00061 00063 // AffineTransformVariable // 00065 AffineTransformVariable::AffineTransformVariable(Variable* vec, 00066 Variable* transformation, 00067 bool call_build_): 00068 inherited(vec, transformation, 00069 vec->isScalar() || vec->isColumnVec() ? transformation->width() 00070 : 1, 00071 vec->isScalar() || vec->isColumnVec() ? 1 00072 : transformation->width(), 00073 call_build_), 00074 force_row_vec(false) 00075 { 00076 if (call_build_) 00077 build_(); 00078 } 00079 00081 // build // 00083 void AffineTransformVariable::build() 00084 { 00085 inherited::build(); 00086 build_(); 00087 } 00088 00090 // build_ // 00092 void AffineTransformVariable::build_() 00093 { 00094 // input1 is vec from constructor 00095 if (input1 && !input1->isVec()) 00096 PLERROR("In AffineTransformVariable: expecting a vector Var (row or column) as first argument"); 00097 } 00098 00100 // declareOptions // 00102 void AffineTransformVariable::declareOptions(OptionList& ol) 00103 { 00104 declareOption(ol, "force_row_vec", &AffineTransformVariable::force_row_vec, 00105 OptionBase::buildoption, 00106 "If set to true, then the resulting vector will always be a row\n" 00107 "vector, even when the input is a column or a scalar."); 00108 00109 inherited::declareOptions(ol); 00110 } 00111 00113 // recomputeSize // 00115 void AffineTransformVariable::recomputeSize(int& l, int& w) const 00116 { 00117 if (input1 && input2) { 00118 if (force_row_vec || (!input1->isScalar() && input1->isRowVec())) { 00119 // Result is a row vector. 00120 l = 1; 00121 w = input2->width(); 00122 } else { 00123 // Result is a column vector. 00124 l = input2->width(); 00125 w = 1; 00126 } 00127 } else 00128 l = w = 0; 00129 } 00130 00132 // fprop // 00134 void AffineTransformVariable::fprop() 00135 { 00136 value << input2->matValue.firstRow(); 00137 Mat lintransform = input2->matValue.subMatRows(1,input2->length()-1); 00138 transposeProductAcc(value, lintransform, input1->value); 00139 } 00140 00142 // bprop // 00144 void AffineTransformVariable::bprop() 00145 { 00146 Mat& afftr = input2->matValue; 00147 int l = afftr.length(); 00148 // Vec bias = afftr.firstRow(); 00149 Mat lintr = afftr.subMatRows(1,l-1); 00150 00151 Mat& afftr_g = input2->matGradient; 00152 Vec bias_g = afftr_g.firstRow(); 00153 Mat lintr_g = afftr_g.subMatRows(1,l-1); 00154 00155 bias_g += gradient; 00156 if(!input1->dont_bprop_here) 00157 productAcc(input1->gradient, lintr, gradient); 00158 externalProductAcc(lintr_g, input1->value, gradient); 00159 } 00160 00161 00162 void AffineTransformVariable::symbolicBprop() 00163 { 00164 PLERROR("AffineTransformVariable::symbolicBprop() not implemented"); 00165 } 00166 00167 } // end of namespace PLearn 00168 00169 00170 /* 00171 Local Variables: 00172 mode:c++ 00173 c-basic-offset:4 00174 c-file-style:"stroustrup" 00175 c-file-offsets:((innamespace . 0)(inline-open . 0)) 00176 indent-tabs-mode:nil 00177 fill-column:79 00178 End: 00179 */ 00180 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :