AlexNet/include/softmaxtree.cuh
Laurent El Shafey 9fdd561586 Initial commit
2024-12-10 08:56:11 -08:00

144 lines
3.7 KiB
Text

/*
* File: softmaxtree.h
* Author: Alex Krizhevsky
*
* Created on September 9, 2012, 5:50 PM
*/
#ifndef SOFTMAXTREE_H
#define SOFTMAXTREE_H
#include <helper_cuda.h>
#include <string>
#include <map>
#include <vector>
#include <algorithm>
#include <assert.h>
#include <nvmatrix.cuh>
#include <matrix.h>
class SoftmaxNode;
class SoftmaxTree;
typedef std::vector<SoftmaxNode*> SoftmaxNodeV;
class SoftmaxNode {
friend class SoftmaxTree;
protected:
SoftmaxNodeV _children;
SoftmaxNode* _parent;
int _depth, _height, _size;
int _label;
/*
* Computes height for entire subtree rooted at this node and populates
* given height->nodes map.
*/
int setDistances(std::map<int, SoftmaxNodeV*>& nodeHeights,
std::map<int, SoftmaxNodeV*>& nodeDepths);
void setNodeCounts(int &nodes, int& leaves);
/*
* Compute the number of leaves in this subtree, which is a good estimate
* of the number of training cases it represents.
*/
int setSizes(ushort* nodeSizes);
public:
SoftmaxNode(SoftmaxNode* parent, int label);
~SoftmaxNode();
SoftmaxNode& addChild(int label);
int getDepth() const;
int getHeight() const;
int getLabel() const;
int getSize() const;
SoftmaxNode* getParent(); // Might be null, so must be pointer
SoftmaxNodeV& getChildren();
};
/*
* numLabels: the number of leaves in the tree (normally 1000)
* numNodes: the total number of nodes in the tree
*/
class SoftmaxTree {
friend class SoftmaxNode;
protected:
SoftmaxNode* _root;
std::map<int, SoftmaxNodeV*> _nodeHeights, _nodeDepths;
/*
* Map from depth --> ushort2[]
* where each ushort2 gives the index and parent index
* of a node at the given depth.
*/
std::map<int, ushort2*> _nodeFwdMeta;
/*
* Map from height --> ushort2[]
* where each ushort2 gives the index and number of children
* of a node at the given height.
*/
std::map<int, ushort2*> _nodeBwdMeta;
/*
* Map from height --> ushort[][]
* where each ushort[] gives children of a given node at a given height.
*/
std::map<int, ushort**> _nodeChildMeta;
/*
* An array of length numNodes with index i storing the number
* of leaves in subtree rooted at node with label i.
*/
ushort* _nodeSizes;
int _numNodes, _numLeaves;
void setDistances();
void setNodeCounts();
void setNodeSizes();
void setFwdMeta();
void setBwdMeta();
void preprocess(NVMatrix& inp);
void postprocess(NVMatrix& inp);
public:
SoftmaxTree(int rootLabel);
~SoftmaxTree();
void finalize();
SoftmaxNode& getRoot();
SoftmaxNodeV& getNodesAtHeight(int height);
SoftmaxNodeV& getNodesAtDepth(int depth);
int getHeight() const;
int getDepth() const;
int getNumLeaves() const;
int getNumNodes() const;
/*
* offsets: (numNodes, numFeatures)
* targets: (numNodes, numFeatures)
*/
void makeWeights(NVMatrix& offsets, NVMatrix& targets);
/*
* grads: (numNodes, numFeatures)
*
* The idea is that grads contains gradients for the leaves
* (i.e. the first numLabels rows), so this routine will
* distribute them up the tree.
*/
void distributeGradients(NVMatrix& grads);
/*
* inc := mom * inc - wc * epsW * weight + epsW * grad
* weight := weight + inc
*
* weights: (numNodes, numFeatures)
* incs: (numNodes, numFeatures)
* grads: (numNodes , numFeatures)
*/
void updateWeights(NVMatrix& weights, NVMatrix& incs, NVMatrix& grads, float epsWBase, float mom, float wcBase);
};
#endif /* SOFTMAXTREE_H */