>

2014년 6월 26일 목요일

std::thread in Mac OS X maveric

Multi-thread programming in C++ with STL is so easy now.

C++ 멀티스레드 프로그래밍 아주 쉬워졌음.

$ clang++ thread_test.cpp -std=c++11 -o thrad_test

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream>
#include <vector>
#include <algorithm>
#include <thread>
void executebuf (std::vector<int>& buf, int i)
//void executebuf (int buf[], int i)
{
    buf[i] = i*10;
    if (i==2) // do something
    for (int j=0; j<1000000; j++)
        int x = j*i*i*i;
    fprintf (stderr, "ebuf= %d\n", i);
}
void execute()
{
    std::cout << "Hello Concurrent world" << std::endl;
}
std::string filename;
void execute2() 
{
    for (int i=0; i<1000000; i++) // do something
        int x = i*i*i*i;
    std::cout << "Hello Concurrent world 2 " << filename << std::endl;
    filename = std::string("printed");
}
int main() 
{
    std::thread th(execute);
    filename = "this is filename.";
    std::thread th2(execute2);
    th.join();
    th2.join();
    std::cout << filename << std::endl;
    std::vector<int> buf(10);
    std::vector<std::thread> t;
    for (int i=0; i<4; i++) 
        t.push_back( std::thread (executebuf, std::ref(buf), i) );
    for (int i=0; i<4; i++)
        t[i].join();
    for (int i=0; i<4; i++)
        printf ("%d  \n", buf[i]);
        return(0);
}
//EOF//
End.

2014년 6월 9일 월요일

lftp mirror

어떤 ftp 사이트의 내용을 통째로 카피해오고 싶을때 사용하는 lftp의 미러링 방법.

This is when you want to copy all the files in an ftp site.

1. You need lftp installed in your computer.

    $ brew install lftp

2. make a bash file with the following contents. For example, make a file named mir.sh with the following.

#!/bin/bash
HOST="ftp_hostname"
USER="ftp_user_id"
PASS="password_for_the_id"
LOG_dir="/tmp/logs"
LCD="local_dir_where_the_files_go"
RCD="dir_of_the_ftp_site"

for ((;;)) // simply repeat. remove for-loop command if the ftp is very stable.
do

DATE=`date '+%Y-%m-%d_%H%M'`
lftp -c "set ftp:list-options -a;
open ftp://$USER:$PASS@$HOST;
lcd $LCD;
cd $RCD;
mirror --verbose --exclude-glob old/ --parallel=10 --log="$LOG_dir/GPL_$DATE" "

sleep 30m 

done 


3. make the file mir.sh executable:

    $ chmod +x mir.sh

4. run the command

    $ mir.sh

5. Wait until it finishes.

6. Press Control-C to stop the bash process.

2014년 5월 28일 수요일

A C/C++ code for Softmax with OpenCV

I searched for a C/C++ code for Softmax written with OpenCV, and found one in
http://eric-yuan.me/softmax-regression-cv. I did not test the code but hopefully it should be good. I will write when a test is done.

The code below is a copy from Eric Yuan's blog http://eric-yuan.me/softmax-regression-cv.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
// ----------------------------------------------------------------------------------------- //
// Softmax regression
 
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <math.h>
#include <iostream>
using namespace cv;
using namespace std;
 
#define elif else if
#define AT at<double>
#define MAX_ITER 100000
 
double cost = 0.0;
Mat grad;
double lrate = 0.1;
double lambda = 0.0;
int nclasses = 2;
 
Mat vec2mat(vector<vector<double> >&vec){
    int cols = vec.size();
    int rows = vec[0].size();
    Mat result(rows, cols, CV_64FC1);
    double *pData;
    for(int i = 0; i<rows; i++){
        pData = result.ptr<double>(i);
        for(int j=0; j<cols; j++){
            pData[j] = vec[j][i];      
        }
    }
    return result;
}
 
Mat vec2colvec(vector<double>& vec){
    int length = vec.size();
    Mat A(length, 1, CV_64FC1);
    for(int i=0; i<length; i++){
        A.AT(i, 0) = vec[i];
    }
    return A;
}
 
Mat vec2rowvec(vector<double>& vec){
    Mat A = vec2colvec(vec);
    return A.t();
}
 
void update_CostFunction_and_Gradient(Mat x, Mat y, Mat weightsMatrix, double lambda){
 
    int nsamples = x.cols;
    int nfeatures = x.rows;
    //calculate cost function
    Mat theta(weightsMatrix);
    Mat M = theta * x;
    Mat temp, temp2;
    temp = Mat::ones(1, M.cols, CV_64FC1);
    reduce(M, temp, 0, CV_REDUCE_SUM);
    temp2 = repeat(temp, nclasses, 1);
    M -= temp2;
    exp(M, M);
    temp = Mat::ones(1, M.cols, CV_64FC1);
    reduce(M, temp, 0, CV_REDUCE_SUM);
    temp2 = repeat(temp, nclasses, 1);
    divide(M, temp2, M);
    Mat groundTruth = Mat::zeros(nclasses, nsamples, CV_64FC1);
    for(int i=0; i<nsamples; i++){
        groundTruth.AT(y.AT(0, i), i) = 1.0;
    }
    Mat logM;
    log(M, logM);
    temp = groundTruth.mul(logM);
    cost = - sum(temp)[0] / nsamples;
    Mat theta2;
    pow(theta, 2.0, theta2);
    cost += sum(theta2)[0] * lambda / 2;
    //calculate gradient
    temp = groundTruth - M;
    temp = temp * x.t();
    grad = - temp / nsamples;
    grad += lambda * theta;
 
}
 
Mat calculateY(Mat x, Mat weightsMatrix){
 
    int nsamples = x.cols;
    int nfeatures = x.rows;
    //calculate cost function
    Mat theta(weightsMatrix);
    Mat M = theta * x;
    Mat temp, temp2;
    temp = Mat::ones(1, M.cols, CV_64FC1);
    reduce(M, temp, 0, CV_REDUCE_SUM);
    temp2 = repeat(temp, nclasses, 1);
    M -= temp2;
    exp(M, M);
    temp = Mat::ones(1, M.cols, CV_64FC1);
    reduce(M, temp, 0, CV_REDUCE_SUM);
    temp2 = repeat(temp, nclasses, 1);
    divide(M, temp2, M);
    log(M, M);
 
    Mat result = Mat::ones(1, M.cols, CV_64FC1);
    for(int i=0; i<M.cols; i++){
        double maxele = M.AT(0, i);
        int which = 0;
        for(int j=1; j<M.rows; j++){
            if(M.AT(j, i) > maxele){
                maxele = M.AT(j, i);
                which = j;
            }
        }
        result.AT(0, i) = which;
    }
    return result;
}
 
void softmax(vector<vector<double> >&vecX, vector<double> &vecY, vector<vector<double> >& testX, vector<double>& testY){
 
    int nsamples = vecX.size();
    int nfeatures = vecX[0].size();
    //change vecX and vecY into matrix or vector.
    Mat y = vec2rowvec(vecY);
    Mat x = vec2mat(vecX);
 
    double init_epsilon = 0.12;
    Mat weightsMatrix = Mat::ones(nclasses, nfeatures, CV_64FC1);
    double *pData;
    for(int i = 0; i<nclasses; i++){
        pData = weightsMatrix.ptr<double>(i);
        for(int j=0; j<nfeatures; j++){
            pData[j] = randu<double>();      
        }
    }
    weightsMatrix = weightsMatrix * (2 * init_epsilon) - init_epsilon;
 
    grad = Mat::zeros(nclasses, nfeatures, CV_64FC1);
 
/*
    //Gradient Checking (remember to disable this part after you're sure the
    //cost function and dJ function are correct)
    update_CostFunction_and_Gradient(x, y, weightsMatrix, lambda);
    Mat dJ(grad);
//    grad.copyTo(dJ);
    cout<<"test!!!!"<<endl;
    double epsilon = 1e-4;
    for(int i=0; i<weightsMatrix.rows; i++){
        for(int j=0; j<weightsMatrix.cols; j++){
            double memo = weightsMatrix.AT(i, j);
            weightsMatrix.AT(i, j) = memo + epsilon;
            update_CostFunction_and_Gradient(x, y, weightsMatrix, lambda);
            double value1 = cost;
            weightsMatrix.AT(i, j) = memo - epsilon;
            update_CostFunction_and_Gradient(x, y, weightsMatrix, lambda);
            double value2 = cost;
            double tp = (value1 - value2) / (2 * epsilon);
            cout<<i<<", "<<j<<", "<<tp<<", "<<dJ.AT(i, j)<<", "<<dJ.AT(i, j) / tp<<endl;
            weightsMatrix.AT(i, j) = memo;
        }
    }
*/
 
    int converge = 0;
    double lastcost = 0.0;
    while(converge < MAX_ITER){
        update_CostFunction_and_Gradient(x, y, weightsMatrix, lambda);
        weightsMatrix -= lrate * grad;
 
        cout<<"learning step: "<<converge<<", Cost function value = "<<cost<<endl;
        if(fabs((cost - lastcost) ) <= 5e-6 && converge > 0) break;
        lastcost = cost;
        ++ converge;
    }
    cout<<"############result#############"<<endl;
 
    Mat yT = vec2rowvec(testY);
    Mat xT = vec2mat(testX);
    Mat result = calculateY(xT, weightsMatrix);
    Mat err(yT);
    err -= result;
    int correct = err.cols;
    for(int i=0; i<err.cols; i++){
        if(err.AT(0, i) != 0) --correct;
    }
    cout<<"correct: "<<correct<<", total: "<<err.cols<<", accuracy: "<<double(correct) / (double)(err.cols)<<endl;
}
 
int main(int argc, char** argv)
{
    long start, end;
    //read training X from .txt file
    FILE *streamX, *streamY;
    streamX = fopen("trainX.txt", "r");
    int numofX = 30;
    vector<vector<double> > vecX;
    double tpdouble;
    int counter = 0;
    while(1){
        if(fscanf(streamX, "%lf", &tpdouble)==EOF) break;
        if(counter / numofX >= vecX.size()){
            vector<double> tpvec;
            vecX.push_back(tpvec);
        }
        vecX[counter / numofX].push_back(tpdouble);
        ++ counter;
    }
    fclose(streamX);
 
    cout<<vecX.size()<<", "<<vecX[0].size()<<endl;
 
    //read training Y from .txt file
    streamY = fopen("trainY.txt", "r");
    vector<double> vecY;
    while(1){
        if(fscanf(streamY, "%lf", &tpdouble)==EOF) break;
        vecY.push_back(tpdouble);
    }
    fclose(streamY);
 
    for(int i = 1; i<vecX.size(); i++){
        if(vecX[i].size() != vecX[i - 1].size()) return 0;
    }
    if(vecX.size() != vecY.size()) return 0;
 
    streamX = fopen("testX.txt", "r");
    vector<vector<double> > vecTX;
    counter = 0;
    while(1){
        if(fscanf(streamX, "%lf", &tpdouble)==EOF) break;
        if(counter / numofX >= vecTX.size()){
            vector<double> tpvec;
            vecTX.push_back(tpvec);
        }
        vecTX[counter / numofX].push_back(tpdouble);
        ++ counter;
    }
    fclose(streamX);
 
    streamY = fopen("testY.txt", "r");
    vector<double> vecTY;
    while(1){
        if(fscanf(streamY, "%lf", &tpdouble)==EOF) break;
        vecTY.push_back(tpdouble);
    }
    fclose(streamY);
 
    start = clock();
    softmax(vecX, vecY, vecTX, vecTY);
    end = clock();
    cout<<"Training used time: "<<((double)(end - start)) / CLOCKS_PER_SEC<<" second"<<endl;
    return 0;
}
// EOF //


Read http://eric-yuan.me/softmax/ about Softmax. The final part of the page says as follows:

SOFTMAX VS MULTI-BINARY CLASSIFIERS

Now let’s retrieve back to the above question about softmax VS multi-binary classifiers. As Prof. Andrew Ng says, which algorithm to use depend on whether the classes are mutually exclusive, which means, whether the classes are mixed. For example:
  • Case 1. classes are [1, 2, 3, 4, 5, 6]
  • Case 2. classes are [1, 2, 3, odd, even, positive]
For case 1, Softmax regression classifier would be fine, in the second case, use multi-logistic regression.