2021-09-22

OpenCV LogisticRegression

OpenCV 也在 ML module 提供了 Logistic Regression。

下面是用來測試 tcl-opencv 新加入的  LogisticRegression command,寫了一個簡單的測試程式來測試:

package require opencv

proc showImage {image columns name} {
    set bigImage [cv::Mat::Mat 0 0 $::cv::CV_32F]

    for {set i 0} {$i < [$image rows]} {incr i} {
        set row [$image rowRange $i [expr $i + 1]]
        set rs  [$row reshape 0 $columns]
        $bigImage push_back $rs

        $row close
        $rs close
    }
    
    set bigImageT [$bigImage transpose]
    ::cv::imshow $name $bigImageT

    $bigImageT close
    $bigImage close
}

#
# Download file from:
# https://github.com/opencv/opencv/tree/master/samples/data/data01.xml
#
set filename "data01.xml"

set f [::cv::FileStorage]
$f open $filename $::cv::FileStorage::READ
set dataMat [$f readMat datamat]
set labelsMat [$f readMat labelsmat]
$f close

# Notice: LogisticRegression label type is CV_32F
set data [$dataMat convert $::cv::CV_32F]
set labels [$labelsMat convert $::cv::CV_32F]
puts "Loading training data... read [$data rows] rows of data"

$dataMat close
$labelsMat close

set data_train [cv::Mat::Mat 0 0 $::cv::CV_32F]
set data_test  [cv::Mat::Mat 0 0 $::cv::CV_32F]
set labels_train  [cv::Mat::Mat 0 0 $::cv::CV_32F]
set labels_test   [cv::Mat::Mat 0 0 $::cv::CV_32F]

for {set i 0} {$i < [$data rows]} {incr i} {
    if {[expr $i%2]==0} {
         $data_train push_back [$data rowRange $i [expr $i + 1]]
         $labels_train push_back [$labels rowRange $i [expr $i + 1]]
    } else {
         $data_test push_back [$data rowRange $i [expr $i + 1]]
         $labels_test push_back [$labels rowRange $i [expr $i + 1]]
    }
}

$data close
$labels close

showImage $data_train 28 "train data"
showImage $data_test 28 "test data"
cv::waitKey 0

set logi [::cv::ml::LogisticRegression]
$logi setLearningRate 0.001
$logi setIterations 10
$logi setRegularization $::cv::ml::LOGISTIC_REG_L2
$logi setTrainMethod $::cv::ml::LOGISTIC_BATCH
$logi setMiniBatchSize 1

puts "Training..."
set trainData [::cv::ml::TrainData $data_train $::cv::ml::ROW_SAMPLE $labels_train]
$logi train $trainData
$trainData close
$data_train close
$labels_train close

$logi save "logi.xml"

puts "Predicting..."
set response [$logi predict $data_test]
set res [lindex $response 1]

$logi close

puts ""
puts "Labels test: "
set labels_test2 [$labels_test convert $::cv::CV_32S]
for {set i 0} {$i < [$labels_test2 rows]} {incr i} {
    puts -nonewline "[$labels_test2 at [list $i 0] 0] "
}
puts ""
puts "Response: "
for {set i 0} {$i < [$res rows]} {incr i} {
    puts -nonewline "[$res at [list $i 0] 0] "
}

puts ""
set correct 0
for {set i 0} {$i < [$labels_test2 rows]} {incr i} {
    if {[$res at [list $i 0] 0]==[$labels_test2 at [list $i 0] 0]} {
        incr correct
    }
}
puts "accuracy: [expr 100 * $correct/[$labels_test2 rows]]"

$res close
$data_test close
$labels_test close
$labels_test2 close

沒有留言: