Adding a weight for each input dimension
This commit is contained in:
+17
-6
@@ -50,13 +50,16 @@ defaultLearningFactor(Network::Progress progress)
|
||||
}
|
||||
|
||||
InputVector::value_type
|
||||
euclidianSquareDistance(const InputVector& a, const InputVector& b)
|
||||
euclidianSquareDistance(const InputVector& a, const InputVector& b, const InputVector& weights)
|
||||
{
|
||||
checkSameDimensions(a, b);
|
||||
checkSameDimensions(a, weights);
|
||||
|
||||
InputVector::value_type res = 0;
|
||||
|
||||
for (std::size_t i = 0; i < a.size(); ++i)
|
||||
{
|
||||
res += (a[i] - b[i]) * (a[i] - b[i]);
|
||||
res += (a[i] - b[i]) * (a[i] - b[i]) * weights[i];
|
||||
}
|
||||
|
||||
return res;
|
||||
@@ -159,6 +162,7 @@ Network::Network(std::size_t width, std::size_t height, std::size_t inputDimCoun
|
||||
: _width(width),
|
||||
_height(height),
|
||||
_inputDimCount(inputDimCount),
|
||||
_weights(inputDimCount, static_cast<InputVector::value_type>(1)),
|
||||
_distanceFunc(euclidianSquareDistance),
|
||||
_learningFactorFunc(defaultLearningFactor),
|
||||
_neighborhoodFunc(defaultNeighborhoodFunc)
|
||||
@@ -180,6 +184,13 @@ _neighborhoodFunc(defaultNeighborhoodFunc)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Network::setDataWeights(const InputVector& weights)
|
||||
{
|
||||
checkSameDimensions(weights, _inputDimCount);
|
||||
|
||||
_weights = weights;
|
||||
}
|
||||
|
||||
InputVector&
|
||||
Network::getRefVector(std::size_t x, std::size_t y)
|
||||
@@ -217,7 +228,7 @@ Network::getClosestRefVector(const InputVector& data) const
|
||||
auto it = std::min_element(_refVectors.begin(), _refVectors.end(),
|
||||
[&](const auto& a, const auto& b)
|
||||
{
|
||||
return (_distanceFunc(a, data) < _distanceFunc(b, data));
|
||||
return (_distanceFunc(a, data, _weights) < _distanceFunc(b, data, _weights));
|
||||
});
|
||||
|
||||
auto index = std::distance(_refVectors.begin(), it);
|
||||
@@ -271,12 +282,12 @@ Network::train(const std::vector<InputVector>& inputData, std::size_t nbIteratio
|
||||
inputDataShuffled.push_back(&input);
|
||||
}
|
||||
|
||||
std::random_device randomDevice;
|
||||
std::mt19937 generator(randomDevice());
|
||||
auto now = std::chrono::system_clock::now();
|
||||
std::mt19937 randGenerator(std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count());
|
||||
|
||||
for (std::size_t i = 0; i < nbIterations; ++i)
|
||||
{
|
||||
std::shuffle(inputDataShuffled.begin(), inputDataShuffled.end(), generator);
|
||||
std::shuffle(inputDataShuffled.begin(), inputDataShuffled.end(), randGenerator);
|
||||
|
||||
for (auto input : inputDataShuffled)
|
||||
{
|
||||
|
||||
@@ -52,6 +52,9 @@ class Network
|
||||
|
||||
Network(std::size_t width, std::size_t height, std::size_t inputDimCount);
|
||||
|
||||
// Set weight for each dimension (default is 1 for each weight)
|
||||
void setDataWeights(const InputVector& weights);
|
||||
|
||||
// data must be normalized
|
||||
void train(const std::vector<InputVector>& dataSamples, std::size_t nbIterations);
|
||||
|
||||
@@ -64,7 +67,7 @@ class Network
|
||||
// i is the current iteration
|
||||
// refVector(i+1) = refVector(i) + LearningFactor(i) * NeighborhoodFunc(i) * (MatchingRefVector - refVector)
|
||||
|
||||
using DistanceFunc = std::function<InputVector::value_type(const InputVector&, const InputVector&)>;
|
||||
using DistanceFunc = std::function<InputVector::value_type(const InputVector& /* a */, const InputVector& /* b */, const InputVector& /* weights */)>;
|
||||
void setDistanceFunc(DistanceFunc distanceFunc);
|
||||
|
||||
struct Progress
|
||||
@@ -91,7 +94,8 @@ class Network
|
||||
std::size_t _height;
|
||||
std::size_t _inputDimCount;
|
||||
|
||||
std::vector<InputVector> _refVectors; // indexed reference vectors
|
||||
InputVector _weights;
|
||||
std::vector<InputVector> _refVectors; // reference vectors
|
||||
|
||||
DistanceFunc _distanceFunc;
|
||||
LearningFactorFunc _learningFactorFunc;
|
||||
|
||||
@@ -29,6 +29,7 @@ int main(int argc, char *argv[])
|
||||
{ 80, -1 },
|
||||
{ 80, -0.75 },
|
||||
{ 240, 0.5 },
|
||||
{ 240, -0.5 },
|
||||
{ 120, -0.5 },
|
||||
{ 140, -0.5 },
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user